Set path Laura: ONLY USE FOR LAURA

#base_path <- "//home.kt.ktzh.ch/B117T23$/Desktop/Riskktaking/Data"
base_path <- "/Users/laurabazzigher/Documents/GitHub/risk_wvs/data/dataset/Data_S3"

Load libraries

library("dplyr")
library("tidyverse")
library("tidyr")
library("readxl")


if (!require("devtools")) install.packages("devtools")
devtools::install_github("aphp/rgho")

library(rgho)

Load dataset to create Hardship-Index

risktaking <- read.csv(file.path(base_path, "gps_wvs_combined.csv"), header=TRUE, as.is=TRUE)
hardship_Original <- read.csv(file.path(base_path, "countryfacts_cleaned.csv"), header=TRUE, as.is=TRUE)
str(risktaking)

Hardship Countrylist

hardship_environment <- risktaking %>%
  group_by(country, isocode) %>%  # Gruppierung nach Land und ISO-Code
  summarise(
    avg_age = mean(age, na.rm = TRUE),  # Durchschnittsalter, NA-Werte ignorieren
    avg_hardship_index = mean(hardship_index, na.rm = TRUE),  # Durchschnittlicher Hardship-Index
    avg_risktaking = mean(risktaking, na.rm = TRUE),  # Durchschnittliches Risikoverhalten
  ) %>%
  rename(COUNTRY = isocode) %>%  # Umbenennen von 'isocode' zu 'COUNTRY'
  arrange(country)  # Sortieren der Ergebnisse nach Land

hardship_Original <- hardship_Original %>%
  rename(COUNTRY = code) %>%
  select(COUNTRY, homiciderate, gdp, infantmortality, lifeexpectancy, gini, femalemale_primedu, hardship_index)

hardship_environment <- hardship_Original %>%
  full_join(hardship_environment, by = "COUNTRY")

# Löschen aller Einträge zu "Serbia and Montenegro"
risktaking <- risktaking %>%
  filter(country != "Serbia and Montenegro")

hardship_Finance <- hardship_environment %>%
  filter(COUNTRY != "Serbia and Montenegro")

head(hardship_environment)

Copy and rename original hardship-Variables

# Umformen des 'hardship_Original' Datensatzes
hardship_environment <- hardship_environment %>%
  mutate(
    HS_original_infantmortality = infantmortality,
    HS_original_lifeexpectancy = lifeexpectancy,
    e_original_gini = gini,
    f_original_gini = gini,
    c_original_homiciderate = homiciderate,
    f_original_gdp = gdp,
    HS_original_genderequality = femalemale_primedu
  )

# Überprüfung der neuen Struktur
str(hardship_environment)

Liste aller verfügbaren Dimensionen

dimensions <- get_gho_dimensions()

Werte für die Dimension “GHO” abrufen

gho_values <- get_gho_values("GHO")
# View(gho_values) # Öffnet die Werte in RStudio

# Beispiel: Suche nach "SA_0000001837"
gho_values[grepl("SA_0000001699", gho_values$Code), ]

Naming:

Hardship:

- Health / Safety (HS), Crime (C), Financial (F), Environmental (E)

Factor:

- HS: Alcohol (alc), Drugs (drg), Nicotine (nic), Mental Health (mh), Sex (sex), Other (oth)

- C: Bodily harm (bh), Antisocial (anti), Theft/ fraud (theft), Other (oth)

- F: Gambling (gam), Investment (inv), Other (oth)

- E: Exposure (exp), Socioeconomic (ses), Other (oth)

Abrufen der Daten für den spezifischen Indikatorcode

e_exp_airdeath100k <- get_gho_data(code = "SDGAIRBODA")  # Household and ambient air pollution attributable death rate (per 100 000 population, age-standardized)
e_exp_disaster <- get_gho_data(code = "SDGDISASTER") # Average death rate due to natural disasters (per 100 000 population)
e_exp_watersanithyg <- get_gho_data(code = "WSH_10")  # Number of diarrhoea deaths from inadequate water, sanitation and hygiene
e_exp_watersanithyg100k <- get_gho_data(code = "WSH_3")  # Water, sanitation and hygiene attributable deaths per 100'000 capita
e_oth_drinkingwater <- get_gho_data(code = "WSH_WATER_BASIC")  # Population using at least basic drinking-water services (%)
e_oth_safewater <- get_gho_data(code = "WSH_WATER_SAFELY_MANAGED")  # Population using safely managed drinking-water services (%)
#e_exp_airdeath <- get_gho_data(code = "AIR_35") # Household and ambient air pollution attributable deaths
#e_exp_airdaly <- get_gho_data(code = "AIR_60") # Household and ambient air pollution attributable DALYs
#e_oth_climatdeath100k <- get_gho_data(code = "CC_3")  # Climate change attributable deaths per 100'000 capita
#e_exp_water <- get_gho_data(code = "WSH_10_WAT")  # Number of diarrhoea deaths from inadequate water
#e_oth_climatdaly100k <- get_gho_data(code = "CC_4")  # Climate change attributable DALYs per 100'000 capita
#e_oth_climatchilddeath100k <- get_gho_data(code = "CC_6")  # Climate change  attributable deaths per 100'000 children under 5 years
#e_oth_climatchilddaly100k <- get_gho_data(code = "CC_8")  # Climate change  attributable DALYs per 100'000 children under 5 years
#e_exp_noise <- get_gho_data(code = "OCC_14")  # Occupational noise attributable DALYs per 100'000 capita
#e_oth_waterpoll <- get_gho_data(code = "WSH_DOMESTIC_WASTe_SAFELY_TREATED")  # SDG 6.3.1 Proportion of safely treated domestic wastewater flows (%)

# Erste Zeilen der Daten anzeigen
#view(e_exp_airdeath100k)
#view(e_exp_disaster)
#view(e_exp_watersanithyg)
#view(e_exp_watersanithyg100k)
#view(e_oth_drinkingwater)
#view(e_oth_safewater)
#view(e_oth_climatstrategy)

Select important rows

e_oth_safewater <- e_oth_safewater %>% select(IndicatorCode, NumericValue, COUNTRY, YEAR, RESIDENCEAREATYPE)
e_oth_drinkingwater <- e_oth_drinkingwater %>% select(IndicatorCode, NumericValue, COUNTRY, YEAR, RESIDENCEAREATYPE)
e_exp_watersanithyg100k <- e_exp_watersanithyg100k %>% select(IndicatorCode, NumericValue, COUNTRY)
e_exp_watersanithyg <- e_exp_watersanithyg %>% select(IndicatorCode, NumericValue, COUNTRY, SEX, AGEGROUP)
e_exp_disaster <- e_exp_disaster %>% select(IndicatorCode, Value, COUNTRY, YEAR)
e_exp_airdeath100k <- e_exp_airdeath100k %>% select(IndicatorCode, NumericValue, COUNTRY, YEAR, SEX, GHECAUSE)

#view(e_exp_airdeath100k)
#head(e_oth_safewater)
#str(e_exp_disaster)
#head(e_oth_drinkingwater)
#head(e_exp_watersanithyg100k)
#head(e_exp_watersanithyg)
#head(e_exp_disaster)
#head(e_exp_airdeath100k)

e_oth_safewater

# 1. Werte in NumericValue in numerische Werte umwandeln
e_oth_safewater <- e_oth_safewater %>%
  mutate(NumericValue = as.numeric(NumericValue))

# 2. Alle Zeilen mit NA in COUNTRY löschen
e_oth_safewater <- e_oth_safewater %>%
  filter(!is.na(COUNTRY))

# 3. Filtern, um nur Zeilen mit RESIDENCEAREATYPE == "TOTL" zu behalten
e_oth_safewater <- e_oth_safewater %>%
  filter(RESIDENCEAREATYPE == "TOTL")

# 4. Die Daten so transformieren, dass die Jahre als Spalten ausgewiesen werden
e_oth_safewater <- e_oth_safewater %>%
  select(COUNTRY, YEAR, NumericValue) %>%  # Relevante Spalten auswählen
  pivot_wider(names_from = YEAR, values_from = NumericValue)  # Jahre als Spalten

# 5. Durchschnitt der Werte zwischen 2005 und 2014 berechnen
e_oth_safewater <- e_oth_safewater %>%
  mutate(
    e_oth_safewater = rowMeans(select(., `2005`:`2014`), na.rm = TRUE) 
  )

# Überprüfen der Ergebnisse
head(e_oth_safewater)

e_oth_drinkingwater

# 1. Werte in NumericValue in numerische Werte umwandeln
e_oth_drinkingwater <- e_oth_drinkingwater %>%
  mutate(NumericValue = as.numeric(NumericValue))

# 2. Alle Zeilen mit NA in COUNTRY löschen
e_oth_drinkingwater <- e_oth_drinkingwater %>%
  filter(!is.na(COUNTRY))

# 3. Filtern, um nur Zeilen mit RESIDENCEAREATYPE == "TOTL" zu behalten
e_oth_drinkingwater <- e_oth_drinkingwater %>%
  filter(RESIDENCEAREATYPE == "TOTL")

# 4. Die Daten so transformieren, dass die Jahre als Spalten ausgewiesen werden
e_oth_drinkingwater <- e_oth_drinkingwater %>%
  select(COUNTRY, YEAR, NumericValue) %>%  # Relevante Spalten auswählen
  pivot_wider(names_from = YEAR, values_from = NumericValue)  # Jahre als Spalten

# 5. Durchschnitt der Werte zwischen 2005 und 2014 berechnen
e_oth_drinkingwater <- e_oth_drinkingwater %>%
  mutate(
    e_oth_drinkingwater = rowMeans(select(., `2005`:`2014`), na.rm = TRUE)  # Durchschnitt berechnen
  )

# Überprüfen der Ergebnisse
head(e_oth_drinkingwater)

e_exp_watersanithyg100k

# Umbenennen der Spalte NumericValue in e_exp_watersanithyg100k
# Sicherstellen, dass NumericValue numerisch ist
e_exp_watersanithyg100k <- e_exp_watersanithyg100k %>%
  mutate(NumericValue = as.numeric(NumericValue))

e_exp_watersanithyg100k <- e_exp_watersanithyg100k %>%
  rename(e_exp_watersanithyg100k = NumericValue)

# Überprüfen der Änderungen
head(e_exp_watersanithyg100k)

e_exp_watersanithyg

# 1. NumericValue in numerische Werte umwandeln und Spalte umbenennen
e_exp_watersanithyg <- e_exp_watersanithyg %>%
  mutate(e_exp_watersanithyg = as.numeric(NumericValue)) %>%  # Umwandlung in numerisch
  select(-NumericValue)  # Entfernen der alten Spalte NumericValue

# 2. Auswahl von SEX == "BTSX"
e_exp_watersanithyg <- e_exp_watersanithyg %>%
  filter(SEX == "BTSX")

# 3. Auswahl von AGEGROUP == "YEARSALL"
e_exp_watersanithyg <- e_exp_watersanithyg %>%
  filter(AGEGROUP == "YEARSALL")

# Überprüfen der Änderungen
head(e_exp_watersanithyg)

e_exp_disaster

library(dplyr)
library(tidyr)

# 1. Spalte `Value` in numerische Werte umwandeln
e_exp_disaster <- e_exp_disaster %>%
  mutate(Value = as.numeric(Value))

# 2. Jahre in Spalten umwandeln
e_exp_disaster <- e_exp_disaster %>%
  pivot_wider(names_from = YEAR, values_from = Value)

# 3. Durchschnitt von 2005 bis 2014 berechnen und ggf. über alle Jahre mitteln
e_exp_disaster <- e_exp_disaster %>%
  rowwise() %>%
  mutate(
    Avg_2005_2014 = mean(c_across(`2005`:`2014`), na.rm = TRUE),  # Durchschnitt von 2005 bis 2014
    e_exp_disaster = ifelse(
      all(is.na(c_across(`2005`:`2014`))),  # Wenn keine Daten von 2005 bis 2014 vorhanden sind
      mean(c_across(where(is.numeric)), na.rm = TRUE),  # Durchschnitt über alle Jahre
      Avg_2005_2014  # Ansonsten bleibt der Durchschnitt von 2005 bis 2014
    )
  ) %>%
  ungroup()

# Überprüfung der Änderungen
head(e_exp_disaster)

e_exp_airdeath100k

library(dplyr)
library(tidyr)

# 1. Spalte NumericValue in numerische Werte umwandeln
e_exp_airdeath100k <- e_exp_airdeath100k %>%
  mutate(NumericValue = as.numeric(NumericValue))

e_exp_airdeath100k <- e_exp_airdeath100k %>%
  filter(!is.na(COUNTRY))

# 2. Auswahl von BTSX in der Spalte SEX
e_exp_airdeath100k <- e_exp_airdeath100k %>%
  filter(SEX == "BTSX")

# 3. Überprüfung und Auswahl von GHE000000
countries_with_GHE000000 <- e_exp_airdeath100k %>%
  filter(GHECAUSE == "GHE000000") %>%
  pull(COUNTRY) %>%
  unique()

e_exp_airdeath100k <- e_exp_airdeath100k %>%
  filter(
    COUNTRY %in% countries_with_GHE000000,  # Nur Länder mit GHE000000 behalten
    GHECAUSE == "GHE000000"  # Nur GHE000000 behalten
  )

# 4. Jahre in separate Spalten ausweisen
e_exp_airdeath100k <- e_exp_airdeath100k %>%
  select(COUNTRY, YEAR, NumericValue) %>%  # Relevante Spalten auswählen
  pivot_wider(names_from = YEAR, values_from = NumericValue)

# 5. Durchschnitt zwischen 2005 und 2014 berechnen
e_exp_airdeath100k <- e_exp_airdeath100k %>%
  rowwise() %>%
  mutate(
    Avg_2005_2014 = mean(c_across(`2010`:`2014`), na.rm = TRUE),  # Durchschnitt 2005–2014
    e_exp_airdeath100k = ifelse(
      all(is.na(c_across(`2010`:`2014`))),  # Wenn keine Werte von 2005–2014
      mean(c_across(where(is.numeric)), na.rm = TRUE),  # Durchschnitt über alle Jahre
      Avg_2005_2014  # Ansonsten 2005–2014 Durchschnitt
    )
  ) %>%
  ungroup()

# Überprüfen der Änderungen
head(e_exp_airdeath100k)
library("WDI")
# Suche nach Indikatoren, die das Wort "unemployment" enthalten
search_results <- WDIsearch(string = "Rule of Law", field = "name")

# Anzeigen der Suchergebnisse
print(search_results)

Naming:

Hardship:

- Health / Safety (HS), Crime (C), Financial (F), Environmental (E)

Factor:

- HS: Alcohol (alc), Drugs (drg), Nicotine (nic), Mental Health (mh), Sex (sex), Other (oth)

- C: Bodily harm (bh), Antisocial (anti), Theft/ fraud (theft), Other (oth)

- F: Gambling (gam), Investment (inv), Other (oth)

- E: Exposure (exp), Socioeconomic (ses), Other (oth)

e_ses_gini: SI.POV.GINI - Gini index

The Gini index measures the extent to which the distribution of income or consumption among individuals or households within an economy deviates from a perfectly equal distribution. A Gini index of 0 represents perfect equality, while an index of 100 implies perfect inequality.

countries <- c("AFG", "DZA", "AND", "ARG", "ARM", "AUS", "AUT", "AZE", "BGD", "BLR", "BOL", "BIH", "BWA", "BRA", "BGR", "BFA", "KHM", "CMR", "CAN", "CHL", "CHN", "COL", "CRI", "HRV", "CYP", "CZE", "ECU", "EGY", "EST", "ETH", "FIN", "FRA", "GEO", "DEU", "GHA", "GRC", "GTM", "HTI", "HKG", "HUN", "IND", "IDN", "IRN", "IRQ", "ISR", "ITA", "JPN", "JOR", "KAZ", "KEN", "KWT", "KGZ", "LBN", "LBY", "LTU", "MWI", "MYS", "MLI", "MEX", "MDA", "MAR", "NLD", "NZL", "NIC", "NGA", "NOR", "PAK", "PSE", "PER", "PHL", "POL", "PRT", "QAT", "ROU", "RUS", "RWA", "SAU", "SRB", "SGP", "SVN", "ZAF", "KOR", "ESP", "LKA", "SUR", "SWE", "CHE", "TWN", "TZA", "THA", "TTO", "TUN", "TUR", "UGA", "UKR", "ARE", "GBR", "USA", "URY", "UZB", "VEN", "VNM", "YEM", "ZMB", "ZWE")   
indicators <- c("SI.POV.GINI") 

# Daten abrufen
e_ses_gini <- WDI(country = countries, indicator = indicators, start = 2005, end = 2014)

# Spalten umbenennen
e_ses_gini <- e_ses_gini %>%
  rename(e_ses_gini = SI.POV.GINI) # Control of Corruption (estimate)

# Daten transformieren: Jahre als Spalten darstellen
e_ses_gini <- e_ses_gini %>%
  pivot_wider(names_from = year, values_from = e_ses_gini)

# Durchschnitt über alle Jahre berechnen und neue Spalte hinzufügen
e_ses_gini <- e_ses_gini %>%
  mutate(e_ses_gini = rowMeans(select(., starts_with("20")), na.rm = TRUE))

# Rename iso3c to COUNTRY
e_ses_gini <- e_ses_gini %>%
  rename(COUNTRY = iso3c)

# Werte mit 0 oder NaN durch NA ersetzen
e_ses_gini <- e_ses_gini %>%
  mutate(e_ses_gini = case_when(
    is.nan(e_ses_gini) ~ NA_real_,
    e_ses_gini == 0 ~ NA_real_,
    TRUE ~ e_ses_gini
  ))

# Zeige die ersten Zeilen der transformierten Daten
#view(e_ses_gini)

e_ses_unemployment: SL.UEM.TOTL.ZS - Unemployment, total (% of total labor force) (modeled ILO estimate)

Unemployment refers to the share of the labor force that is without work but available for and seeking employment.

countries <- c("AFG", "DZA", "AND", "ARG", "ARM", "AUS", "AUT", "AZE", "BGD", "BLR", "BOL", "BIH", "BWA", "BRA", "BGR", "BFA", "KHM", "CMR", "CAN", "CHL", "CHN", "COL", "CRI", "HRV", "CYP", "CZE", "ECU", "EGY", "EST", "ETH", "FIN", "FRA", "GEO", "DEU", "GHA", "GRC", "GTM", "HTI", "HKG", "HUN", "IND", "IDN", "IRN", "IRQ", "ISR", "ITA", "JPN", "JOR", "KAZ", "KEN", "KWT", "KGZ", "LBN", "LBY", "LTU", "MWI", "MYS", "MLI", "MEX", "MDA", "MAR", "NLD", "NZL", "NIC", "NGA", "NOR", "PAK", "PSE", "PER", "PHL", "POL", "PRT", "QAT", "ROU", "RUS", "RWA", "SAU", "SRB", "SGP", "SVN", "ZAF", "KOR", "ESP", "LKA", "SUR", "SWE", "CHE", "TWN", "TZA", "THA", "TTO", "TUN", "TUR", "UGA", "UKR", "ARE", "GBR", "USA", "URY", "UZB", "VEN", "VNM", "YEM", "ZMB", "ZWE")   
indicators <- c("SL.UEM.TOTL.ZS") 

# Daten abrufen
e_ses_unemployment <- WDI(country = countries, indicator = indicators, start = 2005, end = 2014)

# Spalten umbenennen
e_ses_unemployment <- e_ses_unemployment %>%
  rename(e_ses_unemployment = SL.UEM.TOTL.ZS)

# Daten transformieren: Jahre als Spalten darstellen
e_ses_unemployment <- e_ses_unemployment %>%
  pivot_wider(names_from = year, values_from = e_ses_unemployment)

# Durchschnitt über alle Jahre berechnen und neue Spalte hinzufügen
e_ses_unemployment <- e_ses_unemployment %>%
  mutate(e_ses_unemployment = rowMeans(select(., starts_with("20")), na.rm = TRUE))

# Rename iso3c to COUNTRY
e_ses_unemployment <- e_ses_unemployment %>%
  rename(COUNTRY = iso3c)

# Werte mit 0 oder NaN durch NA ersetzen
e_ses_unemployment <- e_ses_unemployment %>%
  mutate(e_ses_unemployment = case_when(
    is.nan(e_ses_unemployment) ~ NA_real_,
    e_ses_unemployment == 0 ~ NA_real_,
    TRUE ~ e_ses_unemployment
  ))

# Zeige die ersten Zeilen der transformierten Daten
#view(e_ses_unemployment)

e_ses_school: SL.UEM.TOTL.ZS - Unemployment, total (% of total labor force) (modeled ILO estimate)

Unemployment refers to the share of the labor force that is without work but available for and seeking employment.

countries <- c("AFG", "DZA", "AND", "ARG", "ARM", "AUS", "AUT", "AZE", "BGD", "BLR", "BOL", "BIH", "BWA", "BRA", "BGR", "BFA", "KHM", "CMR", "CAN", "CHL", "CHN", "COL", "CRI", "HRV", "CYP", "CZE", "ECU", "EGY", "EST", "ETH", "FIN", "FRA", "GEO", "DEU", "GHA", "GRC", "GTM", "HTI", "HKG", "HUN", "IND", "IDN", "IRN", "IRQ", "ISR", "ITA", "JPN", "JOR", "KAZ", "KEN", "KWT", "KGZ", "LBN", "LBY", "LTU", "MWI", "MYS", "MLI", "MEX", "MDA", "MAR", "NLD", "NZL", "NIC", "NGA", "NOR", "PAK", "PSE", "PER", "PHL", "POL", "PRT", "QAT", "ROU", "RUS", "RWA", "SAU", "SRB", "SGP", "SVN", "ZAF", "KOR", "ESP", "LKA", "SUR", "SWE", "CHE", "TWN", "TZA", "THA", "TTO", "TUN", "TUR", "UGA", "UKR", "ARE", "GBR", "USA", "URY", "UZB", "VEN", "VNM", "YEM", "ZMB", "ZWE")   
indicators <- c("SE.ENR.PRSC.FM.ZS") 

# Daten abrufen
e_ses_school <- WDI(country = countries, indicator = indicators, start = 2005, end = 2014)

# Spalten umbenennen
e_ses_school <- e_ses_school %>%
  rename(e_ses_school = `SE.ENR.PRSC.FM.ZS`)

# Daten transformieren: Jahre als Spalten darstellen
e_ses_school <- e_ses_school %>%
  pivot_wider(names_from = year, values_from = e_ses_school)

# Durchschnitt über alle Jahre berechnen und neue Spalte hinzufügen
e_ses_school <- e_ses_school %>%
  mutate(e_ses_school = rowMeans(select(., starts_with("20")), na.rm = TRUE))

# Rename iso3c to COUNTRY
e_ses_school <- e_ses_school %>%
  rename(COUNTRY = iso3c)

# Werte mit 0 oder NaN durch NA ersetzen
e_ses_school <- e_ses_school %>%
  mutate(e_ses_school = case_when(
    is.nan(e_ses_school) ~ NA_real_,
    e_ses_school == 0 ~ NA_real_,
    TRUE ~ e_ses_school
  ))

# Zeige die ersten Zeilen der transformierten Daten
#view(e_ses_school)

e_ses_water: ER.H2O.FWTL.ZS - Annual freshwater withdrawals, total (% of internal resources)

Annual freshwater withdrawals refer to total water withdrawals, not counting evaporation losses from storage basins. Withdrawals also include water from desalination plants in countries where they are a significant source. Withdrawals can exceed 100 percent of total renewable resources where extraction from nonrenewable aquifers or desalination plants is considerable or where there is significant water reuse. Withdrawals for agriculture and industry are total withdrawals for irrigation and livestock production and for direct industrial use (including withdrawals for cooling thermoelectric plants). Withdrawals for domestic uses include drinking water, municipal use or supply, and use for public services, commercial establishments, and homes.

countries <- c("AFG", "DZA", "AND", "ARG", "ARM", "AUS", "AUT", "AZE", "BGD", "BLR", "BOL", "BIH", "BWA", "BRA", "BGR", "BFA", "KHM", "CMR", "CAN", "CHL", "CHN", "COL", "CRI", "HRV", "CYP", "CZE", "ECU", "EGY", "EST", "ETH", "FIN", "FRA", "GEO", "DEU", "GHA", "GRC", "GTM", "HTI", "HKG", "HUN", "IND", "IDN", "IRN", "IRQ", "ISR", "ITA", "JPN", "JOR", "KAZ", "KEN", "KWT", "KGZ", "LBN", "LBY", "LTU", "MWI", "MYS", "MLI", "MEX", "MDA", "MAR", "NLD", "NZL", "NIC", "NGA", "NOR", "PAK", "PSE", "PER", "PHL", "POL", "PRT", "QAT", "ROU", "RUS", "RWA", "SAU", "SRB", "SGP", "SVN", "ZAF", "KOR", "ESP", "LKA", "SUR", "SWE", "CHE", "TWN", "TZA", "THA", "TTO", "TUN", "TUR", "UGA", "UKR", "ARE", "GBR", "USA", "URY", "UZB", "VEN", "VNM", "YEM", "ZMB", "ZWE")   
indicators <- c("ER.H2O.FWTL.ZS") 

# Daten abrufen
e_ses_water <- WDI(country = countries, indicator = indicators, start = 2005, end = 2014)

# Spalten umbenennen
e_ses_water <- e_ses_water %>%
  rename(e_ses_water = `ER.H2O.FWTL.ZS`)

# Daten transformieren: Jahre als Spalten darstellen
e_ses_water <- e_ses_water %>%
  pivot_wider(names_from = year, values_from = e_ses_water)

# Durchschnitt über alle Jahre berechnen und neue Spalte hinzufügen
e_ses_water <- e_ses_water %>%
  mutate(e_ses_water = rowMeans(select(., starts_with("20")), na.rm = TRUE))

# Rename iso3c to COUNTRY
e_ses_water <- e_ses_water %>%
  rename(COUNTRY = iso3c)

# Werte mit 0 oder NaN durch NA ersetzen
e_ses_water <- e_ses_water %>%
  mutate(e_ses_water = case_when(
    is.nan(e_ses_water) ~ NA_real_,
    e_ses_water == 0 ~ NA_real_,
    TRUE ~ e_ses_water
  ))

# Zeige die ersten Zeilen der transformierten Daten
#view(e_ses_water)

Join Specifications to hardship_HS

hardship_environment <- left_join(hardship_environment, e_oth_safewater[, c("COUNTRY", "e_oth_safewater")], by = "COUNTRY")
hardship_environment <- left_join(hardship_environment, e_oth_drinkingwater[, c("COUNTRY", "e_oth_drinkingwater")], by = "COUNTRY")
hardship_environment <- left_join(hardship_environment, e_exp_watersanithyg100k[, c("COUNTRY", "e_exp_watersanithyg100k")], by = "COUNTRY")
hardship_environment <- left_join(hardship_environment, e_exp_watersanithyg[, c("COUNTRY", "e_exp_watersanithyg")], by = "COUNTRY")
hardship_environment <- left_join(hardship_environment, e_exp_disaster[, c("COUNTRY", "e_exp_disaster")], by = "COUNTRY")
hardship_environment <- left_join(hardship_environment, e_exp_airdeath100k[, c("COUNTRY", "e_exp_airdeath100k")], by = "COUNTRY")
hardship_environment <- left_join(hardship_environment, e_ses_gini[, c("COUNTRY", "e_ses_gini")], by = "COUNTRY")
hardship_environment <- left_join(hardship_environment, e_ses_unemployment[, c("COUNTRY", "e_ses_unemployment")], by = "COUNTRY")
hardship_environment <- left_join(hardship_environment, e_ses_school[, c("COUNTRY", "e_ses_school")], by = "COUNTRY")
hardship_environment <- left_join(hardship_environment, e_ses_water[, c("COUNTRY", "e_ses_water")], by = "COUNTRY")

head(hardship_environment)

Missing Countries

# Auswahl aller Spalten, die mit "F_" beginnen
missing_countries <- grep("^e_", names(hardship_environment), value = TRUE)

# Berechnung des Prozentsatzes der fehlenden Werte pro Land
missing_percentages <- hardship_environment %>%
  select(country, all_of(missing_countries)) %>%
  group_by(country) %>%
  summarise_each(funs(sum(is.na(.)) / n() * 100), all_of(missing_countries)) %>%
  mutate(average_missing = rowMeans(select(., -country), na.rm = TRUE))  %>%
  arrange(desc(average_missing))  # Sortiert die Daten absteigend nach dem durchschnittlichen Prozentsatz der fehlenden Werte

# Ausgabe der Ergebnisse
print(missing_percentages)
# Länder HKG, RAW und TWN aus dem Datensatz entfernen
hardship_environment <- hardship_environment %>%
  filter(!COUNTRY %in% c("TWN", "AND"))

hardship_environment <- hardship_environment %>%
  filter(!country %in% c("Serbia and Montenegro"))

head(hardship_environment)
hardship_environment <- hardship_environment %>% select(COUNTRY, country, avg_risktaking, e_original_gini, e_oth_safewater, e_oth_drinkingwater, e_exp_watersanithyg100k, e_exp_watersanithyg, e_exp_disaster, e_exp_airdeath100k, e_ses_gini, e_ses_unemployment, e_ses_school, e_ses_water)
str(hardship_Finance)

Missing values

Prüfung auf den Mechanismus des Fehlens von Daten

# Laden des Pakets
library(mice)
# Little's MCAR-Test durchführen
mcar_test <- mice::md.pattern(hardship_environment, plot = TRUE)


# Ausgabe des Testergebnisses
print(mcar_test)
# Installieren des naniar Pakets, falls noch nicht geschehen
if (!require("naniar")) install.packages("naniar")

# Laden des Pakets
library(naniar)

# Durchführung von Little's MCAR-Test (ähnlich)
mcar_test <- naniar::mcar_test(hardship_environment)

# Ausgabe des Testergebnisses
print(mcar_test)
library(mice)

library(VIM)
aggr_plot <- aggr(hardship_environment, col = c('navyblue', 'red'), numbers = TRUE, sortVars = TRUE, 
                  labels = names(hardship_environment), cex.axis = 0.7, gap = 3, ylab = c("Missing Data", "Pattern"))

vis_miss(hardship_environment)

# Berechnung des Anteils fehlender Werte für jede Variable
missing_percentages <- sapply(hardship_environment, function(x) {
  sum(is.na(x)) / length(x) * 100
})

# Ausgabe der Ergebnisse
missing_percentages
# Darstellung der Ergebnisse in einem Dataframe
missing_summary <- data.frame(
  Variable = names(missing_percentages),
  MissingPercentage = missing_percentages
)

# Sortiere die Variablen nach dem Prozentsatz der fehlenden Werte
missing_summary <- missing_summary[order(-missing_summary$MissingPercentage), ]

# Ausgabe der Tabelle
print(missing_summary)
NA
# Überprüfe, ob alle Variablen tatsächlich numerisch sind
sapply(hardship_environment, function(x) all(is.numeric(x)))
# Erstelle einen Methoden-Vektor
methods <- rep("none", ncol(hardship_environment))
names(methods) <- colnames(hardship_environment)

# Weisen den relevanten Spalten Imputationsmethoden zu
methods["e_original_gini"] <- "pmm"       # Numerisch
methods["e_oth_safewater"] <- "pmm"            # Numerisch
methods["e_exp_watersanithyg100k"] <- "pmm"  # Numerisch
methods["e_ses_gini"] <- "pmm"         # Numerisch
methods["e_ses_school"] <- "pmm"        # Numerisch
methods["e_exp_disaster"] <- "pmm"     # Numerisch
methods["e_exp_airdeath100k"] <- "pmm"        # Numerisch
methods["e_exp_watersanithyg"] <- "pmm"              # Numerisch
methods["e_ses_water"] <- "pmm"           # Numerisch
methods["e_oth_drinkingwater"] <- "pmm"      # Numerisch
methods["e_ses_unemployment"] <- "pmm"           # Numerisch
# Auswahl nur der numerischen Spalten
hardship_environment_numeric <- hardship_environment %>%
  select(where(is.numeric)) %>%
  select(-avg_risktaking)

# Durchführung der Imputation nur für die numerischen Spalten
library(mice)
imputed_data <- mice(
  hardship_environment_numeric,
  m = 20,            # 5 vollständige Datensätze erzeugen
  maxit = 50,       # Maximale Iterationen
  seed = 123        # Reproduzierbarkeit
)
# Zusammenfassung der Imputationsergebnisse
summary(imputed_data)
# Zugriff auf den ersten vollständig imputierten Datensatz
completed_data <- complete(imputed_data, 1)

# Überprüfung der Struktur des vollständigen Datensatzes
str(completed_data)
imputed_data$imp$e_oth_safewater  # Zeigt die imputierten Werte für diese Variable
imputed_data$imp$e_exp_watersanithyg100k  # Zeigt die imputierten Werte für diese Variable
imputed_data$imp$e_ses_gini  # Zeigt die imputierten Werte für diese Variable
imputed_data$imp$e_ses_school  # Zeigt die imputierten Werte für diese Variable
imputed_data$imp$e_exp_disaster  # Zeigt die imputierten Werte für diese Variable
imputed_data$imp$e_exp_airdeath100k  # Zeigt die imputierten Werte für diese Variable
imputed_data$imp$e_exp_watersanithyg  # Zeigt die imputierten Werte für diese Variable
imputed_data$imp$e_ses_water  # Zeigt die imputierten Werte für diese Variable
imputed_data$imp$e_oth_drinkingwater  # Zeigt die imputierten Werte für diese Variable
imputed_data$imp$e_ses_unemployment  # Zeigt die imputierten Werte für diese Variable
imputed_data$imp$e_original_gini

# visualisierung
stripplot(imputed_data, pch = 20, cex = 1.2)  # Verteilung der imputierten Werte

densityplot(imputed_data)  # Dichte der imputierten Werte


# Imputierte Daten extrahieren
completed_data <- complete(imputed_data, action = 1)
library(dplyr)

# Berechnung der Mittelwerte vor der Imputation, ausschließend 'COUNTRY', 'country', 'avg_risktaking'
mean_values_pre_imputation <- hardship_environment %>%
  select(-COUNTRY, -country, -avg_risktaking) %>%  # Ausschluss dieser Spalten
  sapply(mean, na.rm = TRUE)

# Ausgabe der Mittelwerte
print(mean_values_pre_imputation)
# Berechnung der Mittelwerte nach der Imputation
mean_values_post_imputation <- completed_data %>%
  sapply(mean, na.rm = TRUE)

# Ausgabe der Mittelwerte
print(mean_values_post_imputation)
# Vergleich der Mittelwerte vor und nach der Imputation
comparison_data <- data.frame(
  Variable = names(mean_values_pre_imputation),
  PreImputation = mean_values_pre_imputation,
  PostImputation = mean_values_post_imputation
)

# Plotten der Mittelwerte vor und nach der Imputation
library(ggplot2)
ggplot(comparison_data, aes(x = Variable)) +
  geom_bar(aes(y = PreImputation), stat = "identity", fill = "blue", alpha = 0.7) +
  geom_bar(aes(y = PostImputation), stat = "identity", fill = "red", alpha = 0.5) +
  theme_minimal() +
  labs(title = "Vergleich der Mittelwerte vor und nach der Imputation",
       y = "Mittelwert",
       fill = "Legende") +
  scale_fill_manual(values = c("Pre-Imputation" = "blue", "Post-Imputation" = "red")) +
  theme(axis.text.x = element_text(angle = 90, hjust = 1))  # Verbessert die Lesbarkeit der x-Achsenbeschriftungen

# Identifizieren der gemeinsamen Variablennamen
common_names <- intersect(names(mean_values_pre_imputation), names(mean_values_post_imputation))

# Erstellung des Dataframes nur mit den gemeinsamen Variablen
comparison_data <- data.frame(
  Variable = common_names,
  PreImputation = mean_values_pre_imputation[common_names],
  PostImputation = mean_values_post_imputation[common_names]
)

# Überprüfen der Ergebnisse
print(comparison_data)

Füge die imputierten Variablen zurück in den ursprünglichen Datensatz ein:

# Gruppierung entfernen
hardship_environment <- hardship_environment %>%
  ungroup()

# Füge die imputierten Variablen zurück in den Datensatz ein
hardship_environment <- hardship_environment %>%
  mutate(
    e_oth_safewater = completed_data$e_oth_safewater,
    e_exp_watersanithyg100k = completed_data$e_exp_watersanithyg100k,
    e_ses_gini = completed_data$e_ses_gini,
    e_ses_school = completed_data$e_ses_school,
    e_exp_disaster = completed_data$e_exp_disaster,
    e_exp_airdeath100k = completed_data$e_exp_airdeath100k,
    e_exp_watersanithyg = completed_data$e_exp_watersanithyg,
    e_ses_water = completed_data$e_ses_water
  )

# Struktur überprüfen
str(hardship_environment)
sum(is.na(hardship_environment$e_oth_safewater))  # Soll 0 ergeben
sum(is.na(hardship_environment$e_exp_watersanithyg100k))  # Soll 0 ergeben
sum(is.na(hardship_environment$e_ses_gini))  # Soll 0 ergeben
sum(is.na(hardship_environment$e_ses_school))  # Soll 0 ergeben
sum(is.na(hardship_environment$e_exp_disaster))  # Soll 0 ergeben
sum(is.na(hardship_environment$e_exp_airdeath100k))  # Soll 0 ergeben
sum(is.na(hardship_environment$e_exp_watersanithyg))  # Soll 0 ergeben
sum(is.na(hardship_environment$e_ses_water))  # Soll 0 ergeben

check countryfacts

# Plot histograms for each numeric variable
hardship_environment %>% 
  select_if(is.numeric) %>% 
  gather() %>% 
  ggplot(aes(value)) + 
  facet_wrap(~key, scales = "free") + 
  geom_histogram(bins = 30) + 
  theme_minimal()

Ausreisser

# 1. Logarithmische Transformation nur für relevante Variablen
hardship_environment <- hardship_environment %>%
  mutate(
    e_exp_watersanithyg = log(e_exp_watersanithyg + 1), # Nur für große Wertebereiche
    e_ses_water = log(e_ses_water + 1)
  )

# 2. Winsorisierung nur auf Variablen mit potenziellen Ausreißern
winsorize <- function(x, lower_quantile = 0.01, upper_quantile = 0.99) {
  lower <- quantile(x, lower_quantile, na.rm = TRUE)
  upper <- quantile(x, upper_quantile, na.rm = TRUE)
  pmin(pmax(x, lower), upper)
}

hardship_environment <- hardship_environment %>%
  mutate(
    e_exp_disaster = winsorize(e_exp_disaster),
    e_exp_airdeath100k = winsorize(e_exp_airdeath100k),
    e_ses_unemployment = winsorize(e_ses_unemployment)
  )

# 3. Keine Anpassung für andere Variablen (z. B. e_oth_safewater)
# Überprüfen der Struktur nach Transformationen
# view(hardship_environment)
# Anpassung der Daten vor dem Logarithmieren, Ersetzen von Null oder negativen Werten durch einen kleinen positiven Wert
hardship_environment <- hardship_environment %>%
  mutate(
    e_exp_watersanithyg100k = ifelse(e_exp_watersanithyg100k <= 0, 0.1, e_exp_watersanithyg100k),
    e_exp_disaster = ifelse(e_exp_disaster <= 0, 0.1, e_exp_disaster)
  )

# Anwendung der Logarithmus-Transformation mit log1p
hardship_environment <- hardship_environment %>%
  mutate(
    e_exp_watersanithyg100k = log1p(e_exp_watersanithyg100k),
    e_exp_disaster = log1p(e_exp_disaster)
  )

# Überprüfung der Daten nach der Logarithmus-Transformation
summary(hardship_environment$e_exp_watersanithyg100k)
summary(hardship_environment$e_exp_disaster)

Reverse Coding - Standardize and create hardship_environment

library(dplyr)

# Log-transform the variables using dplyr
hardship_environment <- hardship_environment %>%
  mutate(
    e_oth_safewater = log(e_oth_safewater),
    e_ses_gini = log(e_ses_gini),
    e_ses_school = log(e_ses_school),
    e_exp_airdeath100k = log(e_exp_airdeath100k), 
    e_oth_drinkingwater = log(e_oth_drinkingwater), 
    e_ses_unemployment = log(e_ses_unemployment)
  )

head(hardship_environment)
str(hardship_environment)
# Plot histograms for each numeric variable
hardship_environment %>% 
  select_if(is.numeric) %>% 
  gather() %>% 
  ggplot(aes(value)) + 
  facet_wrap(~key, scales = "free") + 
  geom_histogram(bins = 30) + 
  theme_minimal()

Reverse Coding - Standardize and create hardship_HS

# Now apply the scale function after confirming all variables are numeric
hardship_environment <- hardship_environment %>%
  mutate(
    e_oth_drinkingwater = scale(-e_oth_drinkingwater), # reverse coding
    e_oth_safewater = scale(-e_oth_safewater), # reverse coding 
    e_exp_watersanithyg100k = scale(e_exp_watersanithyg100k),
    e_ses_gini = scale(e_ses_gini), 
    e_ses_school = scale(-e_ses_school),
    e_exp_disaster = scale(e_exp_disaster),
    e_exp_airdeath100k = scale(e_exp_airdeath100k),
    e_exp_watersanithyg = scale(e_exp_watersanithyg), 
    e_ses_unemployment = scale(e_ses_unemployment), 
    e_ses_water = scale(e_ses_water)
  ) %>%
  rowwise() %>%
  mutate(
    hardship_HS = mean(c(e_oth_drinkingwater, e_oth_safewater, e_exp_watersanithyg100k, e_ses_gini, e_ses_school, e_exp_disaster, e_exp_airdeath100k, e_exp_watersanithyg, e_ses_unemployment, e_ses_water), na.rm = TRUE)
  ) %>%
  ungroup()

#view(hardship_environment)
head(hardship_environment)
str(hardship_environment)

Correlation Heatmap with all variables

# Erstellung der Heatmap mit Korrelationskoeffizienten
library(ggplot2)
library(reshape2)

# Berechnung der Korrelationsmatrix
cor_matrix <- cor(hardship_environment %>% select_if(is.numeric), use = "complete.obs")

# Umwandlung der Korrelationsmatrix in einen Datensatz für ggplot
melted_cor_matrix <- melt(cor_matrix)

# Erstellen der Heatmap mit Korrelationskoeffizienten
ggplot(melted_cor_matrix, aes(Var1, Var2, fill = value)) +
  geom_tile() +  # Zeichnet die Kacheln
  geom_text(aes(label = sprintf("%.2f", value)), color = "black", size = 3) +  # Fügt die Korrelationskoeffizienten hinzu
  scale_fill_gradient2(midpoint = 0, low = "blue", high = "red", mid = "white", limit = c(-1,1)) +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  labs(fill = "Korrelation", x = NULL, y = NULL) +
  coord_fixed()

# Optional: Speichern der Heatmap als PDF
ggsave("correlation_heatmap.pdf", width = 11, height = 9, path = base_path)

Corrlation Heatmap

# Auswahl relevanter Spalten
selected_vars <- hardship_environment %>% 
  select(avg_risktaking, starts_with("e_"))

# Berechnung der Korrelationsmatrix für ausgewählte Variablen
cor_matrix <- cor(selected_vars, use = "complete.obs")

# Umwandlung der Korrelationsmatrix in einen Datensatz für ggplot
melted_cor_matrix <- melt(cor_matrix)

# Erstellung der Heatmap mit Korrelationskoeffizienten
library(ggplot2)
ggplot(melted_cor_matrix, aes(Var1, Var2, fill = value)) +
  geom_tile() +  # Zeichnet die Kacheln
  geom_text(aes(label = sprintf("%.2f", value)), color = "black", size = 3) +  # Fügt die Korrelationskoeffizienten hinzu
  scale_fill_gradient2(midpoint = 0, low = "blue", high = "red", mid = "white", limit = c(-1,1)) +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1), axis.text.y = element_text(angle = 45, hjust = 1)) +
  labs(fill = "Korrelation", x = NULL, y = NULL) +
  coord_fixed()

Cronbachs Alpha

library(psych)

# Sicherstellen, dass alle relevanten 'HS_'-Spalten ausgewählt werden
items <- hardship_environment %>%
  select(e_original_gini, e_oth_drinkingwater, e_oth_safewater, e_exp_watersanithyg100k, e_ses_gini, e_ses_school, e_exp_disaster, e_exp_airdeath100k, e_exp_watersanithyg, e_ses_unemployment, e_ses_water)

# Berechnung von Cronbachs Alpha
alpha_result <- alpha(items)
print(alpha_result)

Corrlation Heatmap without e_ses_water, e_ses_unemployment

library(dplyr)
library(ggplot2)
library(reshape2)  # Sollte geladen sein, wenn `melt` verwendet wird

# Auswahl relevanter Spalten, ausschließend e_ses_water und e_ses_unemployment
selected_vars <- hardship_environment %>%
  select(avg_risktaking, starts_with("e_"), -e_ses_water, -e_ses_unemployment)

# Berechnung der Korrelationsmatrix für ausgewählte Variablen
cor_matrix <- cor(selected_vars, use = "complete.obs")

# Umwandlung der Korrelationsmatrix in einen Datensatz für ggplot mit `melt` aus dem reshape2-Paket
melted_cor_matrix <- melt(cor_matrix)

# Erstellung der Heatmap mit Korrelationskoeffizienten
ggplot(melted_cor_matrix, aes(Var1, Var2, fill = value)) +
  geom_tile() +  # Zeichnet die Kacheln
  geom_text(aes(label = sprintf("%.2f", value)), color = "black", size = 3) +  # Fügt die Korrelationskoeffizienten hinzu
  scale_fill_gradient2(midpoint = 0, low = "blue", high = "red", mid = "white", limits = c(-1, 1)) +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1), axis.text.y = element_text(angle = 45, hjust = 1)) +
  labs(fill = "Korrelation", x = NULL, y = NULL) +
  coord_fixed()

Cronbachs Alpha

library(psych)

# Sicherstellen, dass alle relevanten 'HS_'-Spalten ausgewählt werden
items <- hardship_environment %>%
  select(e_original_gini, e_oth_drinkingwater, e_oth_safewater, e_exp_watersanithyg100k, e_ses_gini, e_ses_school, e_exp_disaster, e_exp_airdeath100k, e_exp_watersanithyg)

# Berechnung von Cronbachs Alpha
alpha_result <- alpha(items)
print(alpha_result)
hardship_environment <- hardship_environment %>% select(COUNTRY, country, avg_risktaking, e_original_gini, e_oth_drinkingwater, e_oth_safewater, e_exp_watersanithyg100k, e_ses_gini, e_ses_school, e_exp_disaster, e_exp_airdeath100k, e_exp_watersanithyg)
write.csv(hardship_environment, file = file.path(base_path, "hardship_environment.csv"), row.names = FALSE)
LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgcmVzdWx0cyA9ICdoaWRlJywgbWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0UpCnJtKGxpc3QgPSBscygpKQpgYGAKCiMgU2V0IHBhdGggTGF1cmE6IE9OTFkgVVNFIEZPUiBMQVVSQSAKYGBge3J9CiNiYXNlX3BhdGggPC0gIi8vaG9tZS5rdC5rdHpoLmNoL0IxMTdUMjMkL0Rlc2t0b3AvUmlza2t0YWtpbmcvRGF0YSIKYmFzZV9wYXRoIDwtICIvVXNlcnMvbGF1cmFiYXp6aWdoZXIvRG9jdW1lbnRzL0dpdEh1Yi9yaXNrX3d2cy9kYXRhL2RhdGFzZXQvRGF0YV9TMyIKYGBgCgojIExvYWQgbGlicmFyaWVzCmBgYHtyfQpsaWJyYXJ5KCJkcGx5ciIpCmxpYnJhcnkoInRpZHl2ZXJzZSIpCmxpYnJhcnkoInRpZHlyIikKbGlicmFyeSgicmVhZHhsIikKCgppZiAoIXJlcXVpcmUoImRldnRvb2xzIikpIGluc3RhbGwucGFja2FnZXMoImRldnRvb2xzIikKZGV2dG9vbHM6Omluc3RhbGxfZ2l0aHViKCJhcGhwL3JnaG8iKQoKbGlicmFyeShyZ2hvKQpgYGAKCgojIExvYWQgZGF0YXNldCB0byBjcmVhdGUgSGFyZHNoaXAtSW5kZXgKYGBge3J9CnJpc2t0YWtpbmcgPC0gcmVhZC5jc3YoZmlsZS5wYXRoKGJhc2VfcGF0aCwgImdwc193dnNfY29tYmluZWQuY3N2IiksIGhlYWRlcj1UUlVFLCBhcy5pcz1UUlVFKQpoYXJkc2hpcF9PcmlnaW5hbCA8LSByZWFkLmNzdihmaWxlLnBhdGgoYmFzZV9wYXRoLCAiY291bnRyeWZhY3RzX2NsZWFuZWQuY3N2IiksIGhlYWRlcj1UUlVFLCBhcy5pcz1UUlVFKQpzdHIocmlza3Rha2luZykKYGBgCgojIEhhcmRzaGlwIENvdW50cnlsaXN0CmBgYHtyfQpoYXJkc2hpcF9lbnZpcm9ubWVudCA8LSByaXNrdGFraW5nICU+JQogIGdyb3VwX2J5KGNvdW50cnksIGlzb2NvZGUpICU+JSAgIyBHcnVwcGllcnVuZyBuYWNoIExhbmQgdW5kIElTTy1Db2RlCiAgc3VtbWFyaXNlKAogICAgYXZnX2FnZSA9IG1lYW4oYWdlLCBuYS5ybSA9IFRSVUUpLCAgIyBEdXJjaHNjaG5pdHRzYWx0ZXIsIE5BLVdlcnRlIGlnbm9yaWVyZW4KICAgIGF2Z19oYXJkc2hpcF9pbmRleCA9IG1lYW4oaGFyZHNoaXBfaW5kZXgsIG5hLnJtID0gVFJVRSksICAjIER1cmNoc2Nobml0dGxpY2hlciBIYXJkc2hpcC1JbmRleAogICAgYXZnX3Jpc2t0YWtpbmcgPSBtZWFuKHJpc2t0YWtpbmcsIG5hLnJtID0gVFJVRSksICAjIER1cmNoc2Nobml0dGxpY2hlcyBSaXNpa292ZXJoYWx0ZW4KICApICU+JQogIHJlbmFtZShDT1VOVFJZID0gaXNvY29kZSkgJT4lICAjIFVtYmVuZW5uZW4gdm9uICdpc29jb2RlJyB6dSAnQ09VTlRSWScKICBhcnJhbmdlKGNvdW50cnkpICAjIFNvcnRpZXJlbiBkZXIgRXJnZWJuaXNzZSBuYWNoIExhbmQKCmhhcmRzaGlwX09yaWdpbmFsIDwtIGhhcmRzaGlwX09yaWdpbmFsICU+JQogIHJlbmFtZShDT1VOVFJZID0gY29kZSkgJT4lCiAgc2VsZWN0KENPVU5UUlksIGhvbWljaWRlcmF0ZSwgZ2RwLCBpbmZhbnRtb3J0YWxpdHksIGxpZmVleHBlY3RhbmN5LCBnaW5pLCBmZW1hbGVtYWxlX3ByaW1lZHUsIGhhcmRzaGlwX2luZGV4KQoKaGFyZHNoaXBfZW52aXJvbm1lbnQgPC0gaGFyZHNoaXBfT3JpZ2luYWwgJT4lCiAgZnVsbF9qb2luKGhhcmRzaGlwX2Vudmlyb25tZW50LCBieSA9ICJDT1VOVFJZIikKCiMgTMO2c2NoZW4gYWxsZXIgRWludHLDpGdlIHp1ICJTZXJiaWEgYW5kIE1vbnRlbmVncm8iCnJpc2t0YWtpbmcgPC0gcmlza3Rha2luZyAlPiUKICBmaWx0ZXIoY291bnRyeSAhPSAiU2VyYmlhIGFuZCBNb250ZW5lZ3JvIikKCmhhcmRzaGlwX0ZpbmFuY2UgPC0gaGFyZHNoaXBfZW52aXJvbm1lbnQgJT4lCiAgZmlsdGVyKENPVU5UUlkgIT0gIlNlcmJpYSBhbmQgTW9udGVuZWdybyIpCgpoZWFkKGhhcmRzaGlwX2Vudmlyb25tZW50KQpgYGAKCiMgQ29weSBhbmQgcmVuYW1lIG9yaWdpbmFsIGhhcmRzaGlwLVZhcmlhYmxlcwpgYGB7cn0KIyBVbWZvcm1lbiBkZXMgJ2hhcmRzaGlwX09yaWdpbmFsJyBEYXRlbnNhdHplcwpoYXJkc2hpcF9lbnZpcm9ubWVudCA8LSBoYXJkc2hpcF9lbnZpcm9ubWVudCAlPiUKICBtdXRhdGUoCiAgICBIU19vcmlnaW5hbF9pbmZhbnRtb3J0YWxpdHkgPSBpbmZhbnRtb3J0YWxpdHksCiAgICBIU19vcmlnaW5hbF9saWZlZXhwZWN0YW5jeSA9IGxpZmVleHBlY3RhbmN5LAogICAgZV9vcmlnaW5hbF9naW5pID0gZ2luaSwKICAgIGZfb3JpZ2luYWxfZ2luaSA9IGdpbmksCiAgICBjX29yaWdpbmFsX2hvbWljaWRlcmF0ZSA9IGhvbWljaWRlcmF0ZSwKICAgIGZfb3JpZ2luYWxfZ2RwID0gZ2RwLAogICAgSFNfb3JpZ2luYWxfZ2VuZGVyZXF1YWxpdHkgPSBmZW1hbGVtYWxlX3ByaW1lZHUKICApCgojIMOcYmVycHLDvGZ1bmcgZGVyIG5ldWVuIFN0cnVrdHVyCnN0cihoYXJkc2hpcF9lbnZpcm9ubWVudCkKYGBgCgojIExpc3RlIGFsbGVyIHZlcmbDvGdiYXJlbiBEaW1lbnNpb25lbgpgYGB7cn0KZGltZW5zaW9ucyA8LSBnZXRfZ2hvX2RpbWVuc2lvbnMoKQpgYGAKCiMgV2VydGUgZsO8ciBkaWUgRGltZW5zaW9uICJHSE8iIGFicnVmZW4KYGBge3J9Cmdob192YWx1ZXMgPC0gZ2V0X2dob192YWx1ZXMoIkdITyIpCiMgVmlldyhnaG9fdmFsdWVzKSAjIMOWZmZuZXQgZGllIFdlcnRlIGluIFJTdHVkaW8KCiMgQmVpc3BpZWw6IFN1Y2hlIG5hY2ggIlNBXzAwMDAwMDE4MzciCmdob192YWx1ZXNbZ3JlcGwoIlNBXzAwMDAwMDE2OTkiLCBnaG9fdmFsdWVzJENvZGUpLCBdCmBgYAoKIyBOYW1pbmc6IAojIEhhcmRzaGlwOiAKIyAtIEhlYWx0aCAvIFNhZmV0eSAoSFMpLCBDcmltZSAoQyksIEZpbmFuY2lhbCAoRiksIEVudmlyb25tZW50YWwgKEUpCgojIEZhY3RvcjogCiMgLSBIUzogQWxjb2hvbCAoYWxjKSwgRHJ1Z3MgKGRyZyksIE5pY290aW5lIChuaWMpLCBNZW50YWwgSGVhbHRoIChtaCksIFNleCAoc2V4KSwgT3RoZXIgKG90aCkKIyAtIEM6IEJvZGlseSBoYXJtIChiaCksIEFudGlzb2NpYWwgKGFudGkpLCBUaGVmdC8gZnJhdWQgKHRoZWZ0KSwgT3RoZXIgKG90aCkKIyAtIEY6IEdhbWJsaW5nIChnYW0pLCBJbnZlc3RtZW50IChpbnYpLCBPdGhlciAob3RoKQojIC0gRTogRXhwb3N1cmUgKGV4cCksIFNvY2lvZWNvbm9taWMgKHNlcyksIE90aGVyIChvdGgpCgoKCgojIEFicnVmZW4gZGVyIERhdGVuIGbDvHIgZGVuIHNwZXppZmlzY2hlbiBJbmRpa2F0b3Jjb2RlCmBgYHtyfQplX2V4cF9haXJkZWF0aDEwMGsgPC0gZ2V0X2dob19kYXRhKGNvZGUgPSAiU0RHQUlSQk9EQSIpICAjIEhvdXNlaG9sZCBhbmQgYW1iaWVudCBhaXIgcG9sbHV0aW9uIGF0dHJpYnV0YWJsZSBkZWF0aCByYXRlIChwZXIgMTAwIDAwMCBwb3B1bGF0aW9uLCBhZ2Utc3RhbmRhcmRpemVkKQplX2V4cF9kaXNhc3RlciA8LSBnZXRfZ2hvX2RhdGEoY29kZSA9ICJTREdESVNBU1RFUiIpICMgQXZlcmFnZSBkZWF0aCByYXRlIGR1ZSB0byBuYXR1cmFsIGRpc2FzdGVycyAocGVyIDEwMCAwMDAgcG9wdWxhdGlvbikKZV9leHBfd2F0ZXJzYW5pdGh5ZyA8LSBnZXRfZ2hvX2RhdGEoY29kZSA9ICJXU0hfMTAiKSAgIyBOdW1iZXIgb2YgZGlhcnJob2VhIGRlYXRocyBmcm9tIGluYWRlcXVhdGUgd2F0ZXIsIHNhbml0YXRpb24gYW5kIGh5Z2llbmUKZV9leHBfd2F0ZXJzYW5pdGh5ZzEwMGsgPC0gZ2V0X2dob19kYXRhKGNvZGUgPSAiV1NIXzMiKSAgIyBXYXRlciwgc2FuaXRhdGlvbiBhbmQgaHlnaWVuZSBhdHRyaWJ1dGFibGUgZGVhdGhzIHBlciAxMDAnMDAwIGNhcGl0YQplX290aF9kcmlua2luZ3dhdGVyIDwtIGdldF9naG9fZGF0YShjb2RlID0gIldTSF9XQVRFUl9CQVNJQyIpICAjIFBvcHVsYXRpb24gdXNpbmcgYXQgbGVhc3QgYmFzaWMgZHJpbmtpbmctd2F0ZXIgc2VydmljZXMgKCUpCmVfb3RoX3NhZmV3YXRlciA8LSBnZXRfZ2hvX2RhdGEoY29kZSA9ICJXU0hfV0FURVJfU0FGRUxZX01BTkFHRUQiKSAgIyBQb3B1bGF0aW9uIHVzaW5nIHNhZmVseSBtYW5hZ2VkIGRyaW5raW5nLXdhdGVyIHNlcnZpY2VzICglKQojZV9leHBfYWlyZGVhdGggPC0gZ2V0X2dob19kYXRhKGNvZGUgPSAiQUlSXzM1IikgIyBIb3VzZWhvbGQgYW5kIGFtYmllbnQgYWlyIHBvbGx1dGlvbiBhdHRyaWJ1dGFibGUgZGVhdGhzCiNlX2V4cF9haXJkYWx5IDwtIGdldF9naG9fZGF0YShjb2RlID0gIkFJUl82MCIpICMgSG91c2Vob2xkIGFuZCBhbWJpZW50IGFpciBwb2xsdXRpb24gYXR0cmlidXRhYmxlIERBTFlzCiNlX290aF9jbGltYXRkZWF0aDEwMGsgPC0gZ2V0X2dob19kYXRhKGNvZGUgPSAiQ0NfMyIpICAjIENsaW1hdGUgY2hhbmdlIGF0dHJpYnV0YWJsZSBkZWF0aHMgcGVyIDEwMCcwMDAgY2FwaXRhCiNlX2V4cF93YXRlciA8LSBnZXRfZ2hvX2RhdGEoY29kZSA9ICJXU0hfMTBfV0FUIikgICMgTnVtYmVyIG9mIGRpYXJyaG9lYSBkZWF0aHMgZnJvbSBpbmFkZXF1YXRlIHdhdGVyCiNlX290aF9jbGltYXRkYWx5MTAwayA8LSBnZXRfZ2hvX2RhdGEoY29kZSA9ICJDQ180IikgICMgQ2xpbWF0ZSBjaGFuZ2UgYXR0cmlidXRhYmxlIERBTFlzIHBlciAxMDAnMDAwIGNhcGl0YQojZV9vdGhfY2xpbWF0Y2hpbGRkZWF0aDEwMGsgPC0gZ2V0X2dob19kYXRhKGNvZGUgPSAiQ0NfNiIpICAjIENsaW1hdGUgY2hhbmdlICBhdHRyaWJ1dGFibGUgZGVhdGhzIHBlciAxMDAnMDAwIGNoaWxkcmVuIHVuZGVyIDUgeWVhcnMKI2Vfb3RoX2NsaW1hdGNoaWxkZGFseTEwMGsgPC0gZ2V0X2dob19kYXRhKGNvZGUgPSAiQ0NfOCIpICAjIENsaW1hdGUgY2hhbmdlICBhdHRyaWJ1dGFibGUgREFMWXMgcGVyIDEwMCcwMDAgY2hpbGRyZW4gdW5kZXIgNSB5ZWFycwojZV9leHBfbm9pc2UgPC0gZ2V0X2dob19kYXRhKGNvZGUgPSAiT0NDXzE0IikgICMgT2NjdXBhdGlvbmFsIG5vaXNlIGF0dHJpYnV0YWJsZSBEQUxZcyBwZXIgMTAwJzAwMCBjYXBpdGEKI2Vfb3RoX3dhdGVycG9sbCA8LSBnZXRfZ2hvX2RhdGEoY29kZSA9ICJXU0hfRE9NRVNUSUNfV0FTVGVfU0FGRUxZX1RSRUFURUQiKSAgIyBTREcgNi4zLjEgUHJvcG9ydGlvbiBvZiBzYWZlbHkgdHJlYXRlZCBkb21lc3RpYyB3YXN0ZXdhdGVyIGZsb3dzICglKQoKIyBFcnN0ZSBaZWlsZW4gZGVyIERhdGVuIGFuemVpZ2VuCiN2aWV3KGVfZXhwX2FpcmRlYXRoMTAwaykKI3ZpZXcoZV9leHBfZGlzYXN0ZXIpCiN2aWV3KGVfZXhwX3dhdGVyc2FuaXRoeWcpCiN2aWV3KGVfZXhwX3dhdGVyc2FuaXRoeWcxMDBrKQojdmlldyhlX290aF9kcmlua2luZ3dhdGVyKQojdmlldyhlX290aF9zYWZld2F0ZXIpCiN2aWV3KGVfb3RoX2NsaW1hdHN0cmF0ZWd5KQpgYGAKCiMgU2VsZWN0IGltcG9ydGFudCByb3dzIApgYGB7cn0KZV9vdGhfc2FmZXdhdGVyIDwtIGVfb3RoX3NhZmV3YXRlciAlPiUgc2VsZWN0KEluZGljYXRvckNvZGUsIE51bWVyaWNWYWx1ZSwgQ09VTlRSWSwgWUVBUiwgUkVTSURFTkNFQVJFQVRZUEUpCmVfb3RoX2RyaW5raW5nd2F0ZXIgPC0gZV9vdGhfZHJpbmtpbmd3YXRlciAlPiUgc2VsZWN0KEluZGljYXRvckNvZGUsIE51bWVyaWNWYWx1ZSwgQ09VTlRSWSwgWUVBUiwgUkVTSURFTkNFQVJFQVRZUEUpCmVfZXhwX3dhdGVyc2FuaXRoeWcxMDBrIDwtIGVfZXhwX3dhdGVyc2FuaXRoeWcxMDBrICU+JSBzZWxlY3QoSW5kaWNhdG9yQ29kZSwgTnVtZXJpY1ZhbHVlLCBDT1VOVFJZKQplX2V4cF93YXRlcnNhbml0aHlnIDwtIGVfZXhwX3dhdGVyc2FuaXRoeWcgJT4lIHNlbGVjdChJbmRpY2F0b3JDb2RlLCBOdW1lcmljVmFsdWUsIENPVU5UUlksIFNFWCwgQUdFR1JPVVApCmVfZXhwX2Rpc2FzdGVyIDwtIGVfZXhwX2Rpc2FzdGVyICU+JSBzZWxlY3QoSW5kaWNhdG9yQ29kZSwgVmFsdWUsIENPVU5UUlksIFlFQVIpCmVfZXhwX2FpcmRlYXRoMTAwayA8LSBlX2V4cF9haXJkZWF0aDEwMGsgJT4lIHNlbGVjdChJbmRpY2F0b3JDb2RlLCBOdW1lcmljVmFsdWUsIENPVU5UUlksIFlFQVIsIFNFWCwgR0hFQ0FVU0UpCgojdmlldyhlX2V4cF9haXJkZWF0aDEwMGspCiNoZWFkKGVfb3RoX3NhZmV3YXRlcikKI3N0cihlX2V4cF9kaXNhc3RlcikKI2hlYWQoZV9vdGhfZHJpbmtpbmd3YXRlcikKI2hlYWQoZV9leHBfd2F0ZXJzYW5pdGh5ZzEwMGspCiNoZWFkKGVfZXhwX3dhdGVyc2FuaXRoeWcpCiNoZWFkKGVfZXhwX2Rpc2FzdGVyKQojaGVhZChlX2V4cF9haXJkZWF0aDEwMGspCmBgYAoKCiMgZV9vdGhfc2FmZXdhdGVyCmBgYHtyfQojIDEuIFdlcnRlIGluIE51bWVyaWNWYWx1ZSBpbiBudW1lcmlzY2hlIFdlcnRlIHVtd2FuZGVsbgplX290aF9zYWZld2F0ZXIgPC0gZV9vdGhfc2FmZXdhdGVyICU+JQogIG11dGF0ZShOdW1lcmljVmFsdWUgPSBhcy5udW1lcmljKE51bWVyaWNWYWx1ZSkpCgojIDIuIEFsbGUgWmVpbGVuIG1pdCBOQSBpbiBDT1VOVFJZIGzDtnNjaGVuCmVfb3RoX3NhZmV3YXRlciA8LSBlX290aF9zYWZld2F0ZXIgJT4lCiAgZmlsdGVyKCFpcy5uYShDT1VOVFJZKSkKCiMgMy4gRmlsdGVybiwgdW0gbnVyIFplaWxlbiBtaXQgUkVTSURFTkNFQVJFQVRZUEUgPT0gIlRPVEwiIHp1IGJlaGFsdGVuCmVfb3RoX3NhZmV3YXRlciA8LSBlX290aF9zYWZld2F0ZXIgJT4lCiAgZmlsdGVyKFJFU0lERU5DRUFSRUFUWVBFID09ICJUT1RMIikKCiMgNC4gRGllIERhdGVuIHNvIHRyYW5zZm9ybWllcmVuLCBkYXNzIGRpZSBKYWhyZSBhbHMgU3BhbHRlbiBhdXNnZXdpZXNlbiB3ZXJkZW4KZV9vdGhfc2FmZXdhdGVyIDwtIGVfb3RoX3NhZmV3YXRlciAlPiUKICBzZWxlY3QoQ09VTlRSWSwgWUVBUiwgTnVtZXJpY1ZhbHVlKSAlPiUgICMgUmVsZXZhbnRlIFNwYWx0ZW4gYXVzd8OkaGxlbgogIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBZRUFSLCB2YWx1ZXNfZnJvbSA9IE51bWVyaWNWYWx1ZSkgICMgSmFocmUgYWxzIFNwYWx0ZW4KCiMgNS4gRHVyY2hzY2huaXR0IGRlciBXZXJ0ZSB6d2lzY2hlbiAyMDA1IHVuZCAyMDE0IGJlcmVjaG5lbgplX290aF9zYWZld2F0ZXIgPC0gZV9vdGhfc2FmZXdhdGVyICU+JQogIG11dGF0ZSgKICAgIGVfb3RoX3NhZmV3YXRlciA9IHJvd01lYW5zKHNlbGVjdCguLCBgMjAwNWA6YDIwMTRgKSwgbmEucm0gPSBUUlVFKSAKICApCgojIMOcYmVycHLDvGZlbiBkZXIgRXJnZWJuaXNzZQpoZWFkKGVfb3RoX3NhZmV3YXRlcikKYGBgCgojIGVfb3RoX2RyaW5raW5nd2F0ZXIKYGBge3J9CiMgMS4gV2VydGUgaW4gTnVtZXJpY1ZhbHVlIGluIG51bWVyaXNjaGUgV2VydGUgdW13YW5kZWxuCmVfb3RoX2RyaW5raW5nd2F0ZXIgPC0gZV9vdGhfZHJpbmtpbmd3YXRlciAlPiUKICBtdXRhdGUoTnVtZXJpY1ZhbHVlID0gYXMubnVtZXJpYyhOdW1lcmljVmFsdWUpKQoKIyAyLiBBbGxlIFplaWxlbiBtaXQgTkEgaW4gQ09VTlRSWSBsw7ZzY2hlbgplX290aF9kcmlua2luZ3dhdGVyIDwtIGVfb3RoX2RyaW5raW5nd2F0ZXIgJT4lCiAgZmlsdGVyKCFpcy5uYShDT1VOVFJZKSkKCiMgMy4gRmlsdGVybiwgdW0gbnVyIFplaWxlbiBtaXQgUkVTSURFTkNFQVJFQVRZUEUgPT0gIlRPVEwiIHp1IGJlaGFsdGVuCmVfb3RoX2RyaW5raW5nd2F0ZXIgPC0gZV9vdGhfZHJpbmtpbmd3YXRlciAlPiUKICBmaWx0ZXIoUkVTSURFTkNFQVJFQVRZUEUgPT0gIlRPVEwiKQoKIyA0LiBEaWUgRGF0ZW4gc28gdHJhbnNmb3JtaWVyZW4sIGRhc3MgZGllIEphaHJlIGFscyBTcGFsdGVuIGF1c2dld2llc2VuIHdlcmRlbgplX290aF9kcmlua2luZ3dhdGVyIDwtIGVfb3RoX2RyaW5raW5nd2F0ZXIgJT4lCiAgc2VsZWN0KENPVU5UUlksIFlFQVIsIE51bWVyaWNWYWx1ZSkgJT4lICAjIFJlbGV2YW50ZSBTcGFsdGVuIGF1c3fDpGhsZW4KICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gWUVBUiwgdmFsdWVzX2Zyb20gPSBOdW1lcmljVmFsdWUpICAjIEphaHJlIGFscyBTcGFsdGVuCgojIDUuIER1cmNoc2Nobml0dCBkZXIgV2VydGUgendpc2NoZW4gMjAwNSB1bmQgMjAxNCBiZXJlY2huZW4KZV9vdGhfZHJpbmtpbmd3YXRlciA8LSBlX290aF9kcmlua2luZ3dhdGVyICU+JQogIG11dGF0ZSgKICAgIGVfb3RoX2RyaW5raW5nd2F0ZXIgPSByb3dNZWFucyhzZWxlY3QoLiwgYDIwMDVgOmAyMDE0YCksIG5hLnJtID0gVFJVRSkgICMgRHVyY2hzY2huaXR0IGJlcmVjaG5lbgogICkKCiMgw5xiZXJwcsO8ZmVuIGRlciBFcmdlYm5pc3NlCmhlYWQoZV9vdGhfZHJpbmtpbmd3YXRlcikKYGBgCgojIGVfZXhwX3dhdGVyc2FuaXRoeWcxMDBrCmBgYHtyfQojIFVtYmVuZW5uZW4gZGVyIFNwYWx0ZSBOdW1lcmljVmFsdWUgaW4gZV9leHBfd2F0ZXJzYW5pdGh5ZzEwMGsKIyBTaWNoZXJzdGVsbGVuLCBkYXNzIE51bWVyaWNWYWx1ZSBudW1lcmlzY2ggaXN0CmVfZXhwX3dhdGVyc2FuaXRoeWcxMDBrIDwtIGVfZXhwX3dhdGVyc2FuaXRoeWcxMDBrICU+JQogIG11dGF0ZShOdW1lcmljVmFsdWUgPSBhcy5udW1lcmljKE51bWVyaWNWYWx1ZSkpCgplX2V4cF93YXRlcnNhbml0aHlnMTAwayA8LSBlX2V4cF93YXRlcnNhbml0aHlnMTAwayAlPiUKICByZW5hbWUoZV9leHBfd2F0ZXJzYW5pdGh5ZzEwMGsgPSBOdW1lcmljVmFsdWUpCgojIMOcYmVycHLDvGZlbiBkZXIgw4RuZGVydW5nZW4KaGVhZChlX2V4cF93YXRlcnNhbml0aHlnMTAwaykKYGBgCiMgZV9leHBfd2F0ZXJzYW5pdGh5ZwpgYGB7cn0KIyAxLiBOdW1lcmljVmFsdWUgaW4gbnVtZXJpc2NoZSBXZXJ0ZSB1bXdhbmRlbG4gdW5kIFNwYWx0ZSB1bWJlbmVubmVuCmVfZXhwX3dhdGVyc2FuaXRoeWcgPC0gZV9leHBfd2F0ZXJzYW5pdGh5ZyAlPiUKICBtdXRhdGUoZV9leHBfd2F0ZXJzYW5pdGh5ZyA9IGFzLm51bWVyaWMoTnVtZXJpY1ZhbHVlKSkgJT4lICAjIFVtd2FuZGx1bmcgaW4gbnVtZXJpc2NoCiAgc2VsZWN0KC1OdW1lcmljVmFsdWUpICAjIEVudGZlcm5lbiBkZXIgYWx0ZW4gU3BhbHRlIE51bWVyaWNWYWx1ZQoKIyAyLiBBdXN3YWhsIHZvbiBTRVggPT0gIkJUU1giCmVfZXhwX3dhdGVyc2FuaXRoeWcgPC0gZV9leHBfd2F0ZXJzYW5pdGh5ZyAlPiUKICBmaWx0ZXIoU0VYID09ICJCVFNYIikKCiMgMy4gQXVzd2FobCB2b24gQUdFR1JPVVAgPT0gIllFQVJTQUxMIgplX2V4cF93YXRlcnNhbml0aHlnIDwtIGVfZXhwX3dhdGVyc2FuaXRoeWcgJT4lCiAgZmlsdGVyKEFHRUdST1VQID09ICJZRUFSU0FMTCIpCgojIMOcYmVycHLDvGZlbiBkZXIgw4RuZGVydW5nZW4KaGVhZChlX2V4cF93YXRlcnNhbml0aHlnKQpgYGAKCiMgZV9leHBfZGlzYXN0ZXIKYGBge3J9CmxpYnJhcnkoZHBseXIpCmxpYnJhcnkodGlkeXIpCgojIDEuIFNwYWx0ZSBgVmFsdWVgIGluIG51bWVyaXNjaGUgV2VydGUgdW13YW5kZWxuCmVfZXhwX2Rpc2FzdGVyIDwtIGVfZXhwX2Rpc2FzdGVyICU+JQogIG11dGF0ZShWYWx1ZSA9IGFzLm51bWVyaWMoVmFsdWUpKQoKIyAyLiBKYWhyZSBpbiBTcGFsdGVuIHVtd2FuZGVsbgplX2V4cF9kaXNhc3RlciA8LSBlX2V4cF9kaXNhc3RlciAlPiUKICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gWUVBUiwgdmFsdWVzX2Zyb20gPSBWYWx1ZSkKCiMgMy4gRHVyY2hzY2huaXR0IHZvbiAyMDA1IGJpcyAyMDE0IGJlcmVjaG5lbiB1bmQgZ2dmLiDDvGJlciBhbGxlIEphaHJlIG1pdHRlbG4KZV9leHBfZGlzYXN0ZXIgPC0gZV9leHBfZGlzYXN0ZXIgJT4lCiAgcm93d2lzZSgpICU+JQogIG11dGF0ZSgKICAgIEF2Z18yMDA1XzIwMTQgPSBtZWFuKGNfYWNyb3NzKGAyMDA1YDpgMjAxNGApLCBuYS5ybSA9IFRSVUUpLCAgIyBEdXJjaHNjaG5pdHQgdm9uIDIwMDUgYmlzIDIwMTQKICAgIGVfZXhwX2Rpc2FzdGVyID0gaWZlbHNlKAogICAgICBhbGwoaXMubmEoY19hY3Jvc3MoYDIwMDVgOmAyMDE0YCkpKSwgICMgV2VubiBrZWluZSBEYXRlbiB2b24gMjAwNSBiaXMgMjAxNCB2b3JoYW5kZW4gc2luZAogICAgICBtZWFuKGNfYWNyb3NzKHdoZXJlKGlzLm51bWVyaWMpKSwgbmEucm0gPSBUUlVFKSwgICMgRHVyY2hzY2huaXR0IMO8YmVyIGFsbGUgSmFocmUKICAgICAgQXZnXzIwMDVfMjAxNCAgIyBBbnNvbnN0ZW4gYmxlaWJ0IGRlciBEdXJjaHNjaG5pdHQgdm9uIDIwMDUgYmlzIDIwMTQKICAgICkKICApICU+JQogIHVuZ3JvdXAoKQoKIyDDnGJlcnByw7xmdW5nIGRlciDDhG5kZXJ1bmdlbgpoZWFkKGVfZXhwX2Rpc2FzdGVyKQpgYGAKCiMgZV9leHBfYWlyZGVhdGgxMDBrCmBgYHtyfQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KHRpZHlyKQoKIyAxLiBTcGFsdGUgTnVtZXJpY1ZhbHVlIGluIG51bWVyaXNjaGUgV2VydGUgdW13YW5kZWxuCmVfZXhwX2FpcmRlYXRoMTAwayA8LSBlX2V4cF9haXJkZWF0aDEwMGsgJT4lCiAgbXV0YXRlKE51bWVyaWNWYWx1ZSA9IGFzLm51bWVyaWMoTnVtZXJpY1ZhbHVlKSkKCmVfZXhwX2FpcmRlYXRoMTAwayA8LSBlX2V4cF9haXJkZWF0aDEwMGsgJT4lCiAgZmlsdGVyKCFpcy5uYShDT1VOVFJZKSkKCiMgMi4gQXVzd2FobCB2b24gQlRTWCBpbiBkZXIgU3BhbHRlIFNFWAplX2V4cF9haXJkZWF0aDEwMGsgPC0gZV9leHBfYWlyZGVhdGgxMDBrICU+JQogIGZpbHRlcihTRVggPT0gIkJUU1giKQoKIyAzLiDDnGJlcnByw7xmdW5nIHVuZCBBdXN3YWhsIHZvbiBHSEUwMDAwMDAKY291bnRyaWVzX3dpdGhfR0hFMDAwMDAwIDwtIGVfZXhwX2FpcmRlYXRoMTAwayAlPiUKICBmaWx0ZXIoR0hFQ0FVU0UgPT0gIkdIRTAwMDAwMCIpICU+JQogIHB1bGwoQ09VTlRSWSkgJT4lCiAgdW5pcXVlKCkKCmVfZXhwX2FpcmRlYXRoMTAwayA8LSBlX2V4cF9haXJkZWF0aDEwMGsgJT4lCiAgZmlsdGVyKAogICAgQ09VTlRSWSAlaW4lIGNvdW50cmllc193aXRoX0dIRTAwMDAwMCwgICMgTnVyIEzDpG5kZXIgbWl0IEdIRTAwMDAwMCBiZWhhbHRlbgogICAgR0hFQ0FVU0UgPT0gIkdIRTAwMDAwMCIgICMgTnVyIEdIRTAwMDAwMCBiZWhhbHRlbgogICkKCiMgNC4gSmFocmUgaW4gc2VwYXJhdGUgU3BhbHRlbiBhdXN3ZWlzZW4KZV9leHBfYWlyZGVhdGgxMDBrIDwtIGVfZXhwX2FpcmRlYXRoMTAwayAlPiUKICBzZWxlY3QoQ09VTlRSWSwgWUVBUiwgTnVtZXJpY1ZhbHVlKSAlPiUgICMgUmVsZXZhbnRlIFNwYWx0ZW4gYXVzd8OkaGxlbgogIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBZRUFSLCB2YWx1ZXNfZnJvbSA9IE51bWVyaWNWYWx1ZSkKCiMgNS4gRHVyY2hzY2huaXR0IHp3aXNjaGVuIDIwMDUgdW5kIDIwMTQgYmVyZWNobmVuCmVfZXhwX2FpcmRlYXRoMTAwayA8LSBlX2V4cF9haXJkZWF0aDEwMGsgJT4lCiAgcm93d2lzZSgpICU+JQogIG11dGF0ZSgKICAgIEF2Z18yMDA1XzIwMTQgPSBtZWFuKGNfYWNyb3NzKGAyMDEwYDpgMjAxNGApLCBuYS5ybSA9IFRSVUUpLCAgIyBEdXJjaHNjaG5pdHQgMjAwNeKAkzIwMTQKICAgIGVfZXhwX2FpcmRlYXRoMTAwayA9IGlmZWxzZSgKICAgICAgYWxsKGlzLm5hKGNfYWNyb3NzKGAyMDEwYDpgMjAxNGApKSksICAjIFdlbm4ga2VpbmUgV2VydGUgdm9uIDIwMDXigJMyMDE0CiAgICAgIG1lYW4oY19hY3Jvc3Mod2hlcmUoaXMubnVtZXJpYykpLCBuYS5ybSA9IFRSVUUpLCAgIyBEdXJjaHNjaG5pdHQgw7xiZXIgYWxsZSBKYWhyZQogICAgICBBdmdfMjAwNV8yMDE0ICAjIEFuc29uc3RlbiAyMDA14oCTMjAxNCBEdXJjaHNjaG5pdHQKICAgICkKICApICU+JQogIHVuZ3JvdXAoKQoKIyDDnGJlcnByw7xmZW4gZGVyIMOEbmRlcnVuZ2VuCmhlYWQoZV9leHBfYWlyZGVhdGgxMDBrKQpgYGAKYGBge3J9CmxpYnJhcnkoIldESSIpCiMgU3VjaGUgbmFjaCBJbmRpa2F0b3JlbiwgZGllIGRhcyBXb3J0ICJ1bmVtcGxveW1lbnQiIGVudGhhbHRlbgpzZWFyY2hfcmVzdWx0cyA8LSBXRElzZWFyY2goc3RyaW5nID0gIlJ1bGUgb2YgTGF3IiwgZmllbGQgPSAibmFtZSIpCgojIEFuemVpZ2VuIGRlciBTdWNoZXJnZWJuaXNzZQpwcmludChzZWFyY2hfcmVzdWx0cykKYGBgCgojIE5hbWluZzogCiMgSGFyZHNoaXA6IAojIC0gSGVhbHRoIC8gU2FmZXR5IChIUyksIENyaW1lIChDKSwgRmluYW5jaWFsIChGKSwgRW52aXJvbm1lbnRhbCAoRSkKCiMgRmFjdG9yOiAKIyAtIEhTOiBBbGNvaG9sIChhbGMpLCBEcnVncyAoZHJnKSwgTmljb3RpbmUgKG5pYyksIE1lbnRhbCBIZWFsdGggKG1oKSwgU2V4IChzZXgpLCBPdGhlciAob3RoKQojIC0gQzogQm9kaWx5IGhhcm0gKGJoKSwgQW50aXNvY2lhbCAoYW50aSksIFRoZWZ0LyBmcmF1ZCAodGhlZnQpLCBPdGhlciAob3RoKQojIC0gRjogR2FtYmxpbmcgKGdhbSksIEludmVzdG1lbnQgKGludiksIE90aGVyIChvdGgpCiMgLSBFOiBFeHBvc3VyZSAoZXhwKSwgU29jaW9lY29ub21pYyAoc2VzKSwgT3RoZXIgKG90aCkKCgojIGVfc2VzX2dpbmk6IFNJLlBPVi5HSU5JCS0gR2luaSBpbmRleAojIyBUaGUgR2luaSBpbmRleCBtZWFzdXJlcyB0aGUgZXh0ZW50IHRvIHdoaWNoIHRoZSBkaXN0cmlidXRpb24gb2YgaW5jb21lIG9yIGNvbnN1bXB0aW9uIGFtb25nIGluZGl2aWR1YWxzIG9yIGhvdXNlaG9sZHMgd2l0aGluIGFuIGVjb25vbXkgZGV2aWF0ZXMgZnJvbSBhIHBlcmZlY3RseSBlcXVhbCBkaXN0cmlidXRpb24uIEEgR2luaSBpbmRleCBvZiAwIHJlcHJlc2VudHMgcGVyZmVjdCBlcXVhbGl0eSwgd2hpbGUgYW4gaW5kZXggb2YgMTAwIGltcGxpZXMgcGVyZmVjdCBpbmVxdWFsaXR5LgpgYGB7cn0KY291bnRyaWVzIDwtIGMoIkFGRyIsICJEWkEiLCAiQU5EIiwgIkFSRyIsICJBUk0iLCAiQVVTIiwgIkFVVCIsICJBWkUiLCAiQkdEIiwgIkJMUiIsICJCT0wiLCAiQklIIiwgIkJXQSIsICJCUkEiLCAiQkdSIiwgIkJGQSIsICJLSE0iLCAiQ01SIiwgIkNBTiIsICJDSEwiLCAiQ0hOIiwgIkNPTCIsICJDUkkiLCAiSFJWIiwgIkNZUCIsICJDWkUiLCAiRUNVIiwgIkVHWSIsICJFU1QiLCAiRVRIIiwgIkZJTiIsICJGUkEiLCAiR0VPIiwgIkRFVSIsICJHSEEiLCAiR1JDIiwgIkdUTSIsICJIVEkiLCAiSEtHIiwgIkhVTiIsICJJTkQiLCAiSUROIiwgIklSTiIsICJJUlEiLCAiSVNSIiwgIklUQSIsICJKUE4iLCAiSk9SIiwgIktBWiIsICJLRU4iLCAiS1dUIiwgIktHWiIsICJMQk4iLCAiTEJZIiwgIkxUVSIsICJNV0kiLCAiTVlTIiwgIk1MSSIsICJNRVgiLCAiTURBIiwgIk1BUiIsICJOTEQiLCAiTlpMIiwgIk5JQyIsICJOR0EiLCAiTk9SIiwgIlBBSyIsICJQU0UiLCAiUEVSIiwgIlBITCIsICJQT0wiLCAiUFJUIiwgIlFBVCIsICJST1UiLCAiUlVTIiwgIlJXQSIsICJTQVUiLCAiU1JCIiwgIlNHUCIsICJTVk4iLCAiWkFGIiwgIktPUiIsICJFU1AiLCAiTEtBIiwgIlNVUiIsICJTV0UiLCAiQ0hFIiwgIlRXTiIsICJUWkEiLCAiVEhBIiwgIlRUTyIsICJUVU4iLCAiVFVSIiwgIlVHQSIsICJVS1IiLCAiQVJFIiwgIkdCUiIsICJVU0EiLCAiVVJZIiwgIlVaQiIsICJWRU4iLCAiVk5NIiwgIllFTSIsICJaTUIiLCAiWldFIikgICAKaW5kaWNhdG9ycyA8LSBjKCJTSS5QT1YuR0lOSSIpIAoKIyBEYXRlbiBhYnJ1ZmVuCmVfc2VzX2dpbmkgPC0gV0RJKGNvdW50cnkgPSBjb3VudHJpZXMsIGluZGljYXRvciA9IGluZGljYXRvcnMsIHN0YXJ0ID0gMjAwNSwgZW5kID0gMjAxNCkKCiMgU3BhbHRlbiB1bWJlbmVubmVuCmVfc2VzX2dpbmkgPC0gZV9zZXNfZ2luaSAlPiUKICByZW5hbWUoZV9zZXNfZ2luaSA9IFNJLlBPVi5HSU5JKSAjIENvbnRyb2wgb2YgQ29ycnVwdGlvbiAoZXN0aW1hdGUpCgojIERhdGVuIHRyYW5zZm9ybWllcmVuOiBKYWhyZSBhbHMgU3BhbHRlbiBkYXJzdGVsbGVuCmVfc2VzX2dpbmkgPC0gZV9zZXNfZ2luaSAlPiUKICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0geWVhciwgdmFsdWVzX2Zyb20gPSBlX3Nlc19naW5pKQoKIyBEdXJjaHNjaG5pdHQgw7xiZXIgYWxsZSBKYWhyZSBiZXJlY2huZW4gdW5kIG5ldWUgU3BhbHRlIGhpbnp1ZsO8Z2VuCmVfc2VzX2dpbmkgPC0gZV9zZXNfZ2luaSAlPiUKICBtdXRhdGUoZV9zZXNfZ2luaSA9IHJvd01lYW5zKHNlbGVjdCguLCBzdGFydHNfd2l0aCgiMjAiKSksIG5hLnJtID0gVFJVRSkpCgojIFJlbmFtZSBpc28zYyB0byBDT1VOVFJZCmVfc2VzX2dpbmkgPC0gZV9zZXNfZ2luaSAlPiUKICByZW5hbWUoQ09VTlRSWSA9IGlzbzNjKQoKIyBXZXJ0ZSBtaXQgMCBvZGVyIE5hTiBkdXJjaCBOQSBlcnNldHplbgplX3Nlc19naW5pIDwtIGVfc2VzX2dpbmkgJT4lCiAgbXV0YXRlKGVfc2VzX2dpbmkgPSBjYXNlX3doZW4oCiAgICBpcy5uYW4oZV9zZXNfZ2luaSkgfiBOQV9yZWFsXywKICAgIGVfc2VzX2dpbmkgPT0gMCB+IE5BX3JlYWxfLAogICAgVFJVRSB+IGVfc2VzX2dpbmkKICApKQoKIyBaZWlnZSBkaWUgZXJzdGVuIFplaWxlbiBkZXIgdHJhbnNmb3JtaWVydGVuIERhdGVuCiN2aWV3KGVfc2VzX2dpbmkpCmBgYAoKCgojIGVfc2VzX3VuZW1wbG95bWVudDogU0wuVUVNLlRPVEwuWlMgLSBVbmVtcGxveW1lbnQsIHRvdGFsICglIG9mIHRvdGFsIGxhYm9yIGZvcmNlKSAobW9kZWxlZCBJTE8gZXN0aW1hdGUpCiMjIFVuZW1wbG95bWVudCByZWZlcnMgdG8gdGhlIHNoYXJlIG9mIHRoZSBsYWJvciBmb3JjZSB0aGF0IGlzIHdpdGhvdXQgd29yayBidXQgYXZhaWxhYmxlIGZvciBhbmQgc2Vla2luZyBlbXBsb3ltZW50LgpgYGB7cn0KY291bnRyaWVzIDwtIGMoIkFGRyIsICJEWkEiLCAiQU5EIiwgIkFSRyIsICJBUk0iLCAiQVVTIiwgIkFVVCIsICJBWkUiLCAiQkdEIiwgIkJMUiIsICJCT0wiLCAiQklIIiwgIkJXQSIsICJCUkEiLCAiQkdSIiwgIkJGQSIsICJLSE0iLCAiQ01SIiwgIkNBTiIsICJDSEwiLCAiQ0hOIiwgIkNPTCIsICJDUkkiLCAiSFJWIiwgIkNZUCIsICJDWkUiLCAiRUNVIiwgIkVHWSIsICJFU1QiLCAiRVRIIiwgIkZJTiIsICJGUkEiLCAiR0VPIiwgIkRFVSIsICJHSEEiLCAiR1JDIiwgIkdUTSIsICJIVEkiLCAiSEtHIiwgIkhVTiIsICJJTkQiLCAiSUROIiwgIklSTiIsICJJUlEiLCAiSVNSIiwgIklUQSIsICJKUE4iLCAiSk9SIiwgIktBWiIsICJLRU4iLCAiS1dUIiwgIktHWiIsICJMQk4iLCAiTEJZIiwgIkxUVSIsICJNV0kiLCAiTVlTIiwgIk1MSSIsICJNRVgiLCAiTURBIiwgIk1BUiIsICJOTEQiLCAiTlpMIiwgIk5JQyIsICJOR0EiLCAiTk9SIiwgIlBBSyIsICJQU0UiLCAiUEVSIiwgIlBITCIsICJQT0wiLCAiUFJUIiwgIlFBVCIsICJST1UiLCAiUlVTIiwgIlJXQSIsICJTQVUiLCAiU1JCIiwgIlNHUCIsICJTVk4iLCAiWkFGIiwgIktPUiIsICJFU1AiLCAiTEtBIiwgIlNVUiIsICJTV0UiLCAiQ0hFIiwgIlRXTiIsICJUWkEiLCAiVEhBIiwgIlRUTyIsICJUVU4iLCAiVFVSIiwgIlVHQSIsICJVS1IiLCAiQVJFIiwgIkdCUiIsICJVU0EiLCAiVVJZIiwgIlVaQiIsICJWRU4iLCAiVk5NIiwgIllFTSIsICJaTUIiLCAiWldFIikgICAKaW5kaWNhdG9ycyA8LSBjKCJTTC5VRU0uVE9UTC5aUyIpIAoKIyBEYXRlbiBhYnJ1ZmVuCmVfc2VzX3VuZW1wbG95bWVudCA8LSBXREkoY291bnRyeSA9IGNvdW50cmllcywgaW5kaWNhdG9yID0gaW5kaWNhdG9ycywgc3RhcnQgPSAyMDA1LCBlbmQgPSAyMDE0KQoKIyBTcGFsdGVuIHVtYmVuZW5uZW4KZV9zZXNfdW5lbXBsb3ltZW50IDwtIGVfc2VzX3VuZW1wbG95bWVudCAlPiUKICByZW5hbWUoZV9zZXNfdW5lbXBsb3ltZW50ID0gU0wuVUVNLlRPVEwuWlMpCgojIERhdGVuIHRyYW5zZm9ybWllcmVuOiBKYWhyZSBhbHMgU3BhbHRlbiBkYXJzdGVsbGVuCmVfc2VzX3VuZW1wbG95bWVudCA8LSBlX3Nlc191bmVtcGxveW1lbnQgJT4lCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHllYXIsIHZhbHVlc19mcm9tID0gZV9zZXNfdW5lbXBsb3ltZW50KQoKIyBEdXJjaHNjaG5pdHQgw7xiZXIgYWxsZSBKYWhyZSBiZXJlY2huZW4gdW5kIG5ldWUgU3BhbHRlIGhpbnp1ZsO8Z2VuCmVfc2VzX3VuZW1wbG95bWVudCA8LSBlX3Nlc191bmVtcGxveW1lbnQgJT4lCiAgbXV0YXRlKGVfc2VzX3VuZW1wbG95bWVudCA9IHJvd01lYW5zKHNlbGVjdCguLCBzdGFydHNfd2l0aCgiMjAiKSksIG5hLnJtID0gVFJVRSkpCgojIFJlbmFtZSBpc28zYyB0byBDT1VOVFJZCmVfc2VzX3VuZW1wbG95bWVudCA8LSBlX3Nlc191bmVtcGxveW1lbnQgJT4lCiAgcmVuYW1lKENPVU5UUlkgPSBpc28zYykKCiMgV2VydGUgbWl0IDAgb2RlciBOYU4gZHVyY2ggTkEgZXJzZXR6ZW4KZV9zZXNfdW5lbXBsb3ltZW50IDwtIGVfc2VzX3VuZW1wbG95bWVudCAlPiUKICBtdXRhdGUoZV9zZXNfdW5lbXBsb3ltZW50ID0gY2FzZV93aGVuKAogICAgaXMubmFuKGVfc2VzX3VuZW1wbG95bWVudCkgfiBOQV9yZWFsXywKICAgIGVfc2VzX3VuZW1wbG95bWVudCA9PSAwIH4gTkFfcmVhbF8sCiAgICBUUlVFIH4gZV9zZXNfdW5lbXBsb3ltZW50CiAgKSkKCiMgWmVpZ2UgZGllIGVyc3RlbiBaZWlsZW4gZGVyIHRyYW5zZm9ybWllcnRlbiBEYXRlbgojdmlldyhlX3Nlc191bmVtcGxveW1lbnQpCmBgYAoKCiMgZV9zZXNfc2Nob29sOiBTTC5VRU0uVE9UTC5aUyAtIFVuZW1wbG95bWVudCwgdG90YWwgKCUgb2YgdG90YWwgbGFib3IgZm9yY2UpIChtb2RlbGVkIElMTyBlc3RpbWF0ZSkKIyMgVW5lbXBsb3ltZW50IHJlZmVycyB0byB0aGUgc2hhcmUgb2YgdGhlIGxhYm9yIGZvcmNlIHRoYXQgaXMgd2l0aG91dCB3b3JrIGJ1dCBhdmFpbGFibGUgZm9yIGFuZCBzZWVraW5nIGVtcGxveW1lbnQuCmBgYHtyfQpjb3VudHJpZXMgPC0gYygiQUZHIiwgIkRaQSIsICJBTkQiLCAiQVJHIiwgIkFSTSIsICJBVVMiLCAiQVVUIiwgIkFaRSIsICJCR0QiLCAiQkxSIiwgIkJPTCIsICJCSUgiLCAiQldBIiwgIkJSQSIsICJCR1IiLCAiQkZBIiwgIktITSIsICJDTVIiLCAiQ0FOIiwgIkNITCIsICJDSE4iLCAiQ09MIiwgIkNSSSIsICJIUlYiLCAiQ1lQIiwgIkNaRSIsICJFQ1UiLCAiRUdZIiwgIkVTVCIsICJFVEgiLCAiRklOIiwgIkZSQSIsICJHRU8iLCAiREVVIiwgIkdIQSIsICJHUkMiLCAiR1RNIiwgIkhUSSIsICJIS0ciLCAiSFVOIiwgIklORCIsICJJRE4iLCAiSVJOIiwgIklSUSIsICJJU1IiLCAiSVRBIiwgIkpQTiIsICJKT1IiLCAiS0FaIiwgIktFTiIsICJLV1QiLCAiS0daIiwgIkxCTiIsICJMQlkiLCAiTFRVIiwgIk1XSSIsICJNWVMiLCAiTUxJIiwgIk1FWCIsICJNREEiLCAiTUFSIiwgIk5MRCIsICJOWkwiLCAiTklDIiwgIk5HQSIsICJOT1IiLCAiUEFLIiwgIlBTRSIsICJQRVIiLCAiUEhMIiwgIlBPTCIsICJQUlQiLCAiUUFUIiwgIlJPVSIsICJSVVMiLCAiUldBIiwgIlNBVSIsICJTUkIiLCAiU0dQIiwgIlNWTiIsICJaQUYiLCAiS09SIiwgIkVTUCIsICJMS0EiLCAiU1VSIiwgIlNXRSIsICJDSEUiLCAiVFdOIiwgIlRaQSIsICJUSEEiLCAiVFRPIiwgIlRVTiIsICJUVVIiLCAiVUdBIiwgIlVLUiIsICJBUkUiLCAiR0JSIiwgIlVTQSIsICJVUlkiLCAiVVpCIiwgIlZFTiIsICJWTk0iLCAiWUVNIiwgIlpNQiIsICJaV0UiKSAgIAppbmRpY2F0b3JzIDwtIGMoIlNFLkVOUi5QUlNDLkZNLlpTIikgCgojIERhdGVuIGFicnVmZW4KZV9zZXNfc2Nob29sIDwtIFdESShjb3VudHJ5ID0gY291bnRyaWVzLCBpbmRpY2F0b3IgPSBpbmRpY2F0b3JzLCBzdGFydCA9IDIwMDUsIGVuZCA9IDIwMTQpCgojIFNwYWx0ZW4gdW1iZW5lbm5lbgplX3Nlc19zY2hvb2wgPC0gZV9zZXNfc2Nob29sICU+JQogIHJlbmFtZShlX3Nlc19zY2hvb2wgPSBgU0UuRU5SLlBSU0MuRk0uWlNgKQoKIyBEYXRlbiB0cmFuc2Zvcm1pZXJlbjogSmFocmUgYWxzIFNwYWx0ZW4gZGFyc3RlbGxlbgplX3Nlc19zY2hvb2wgPC0gZV9zZXNfc2Nob29sICU+JQogIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSB5ZWFyLCB2YWx1ZXNfZnJvbSA9IGVfc2VzX3NjaG9vbCkKCiMgRHVyY2hzY2huaXR0IMO8YmVyIGFsbGUgSmFocmUgYmVyZWNobmVuIHVuZCBuZXVlIFNwYWx0ZSBoaW56dWbDvGdlbgplX3Nlc19zY2hvb2wgPC0gZV9zZXNfc2Nob29sICU+JQogIG11dGF0ZShlX3Nlc19zY2hvb2wgPSByb3dNZWFucyhzZWxlY3QoLiwgc3RhcnRzX3dpdGgoIjIwIikpLCBuYS5ybSA9IFRSVUUpKQoKIyBSZW5hbWUgaXNvM2MgdG8gQ09VTlRSWQplX3Nlc19zY2hvb2wgPC0gZV9zZXNfc2Nob29sICU+JQogIHJlbmFtZShDT1VOVFJZID0gaXNvM2MpCgojIFdlcnRlIG1pdCAwIG9kZXIgTmFOIGR1cmNoIE5BIGVyc2V0emVuCmVfc2VzX3NjaG9vbCA8LSBlX3Nlc19zY2hvb2wgJT4lCiAgbXV0YXRlKGVfc2VzX3NjaG9vbCA9IGNhc2Vfd2hlbigKICAgIGlzLm5hbihlX3Nlc19zY2hvb2wpIH4gTkFfcmVhbF8sCiAgICBlX3Nlc19zY2hvb2wgPT0gMCB+IE5BX3JlYWxfLAogICAgVFJVRSB+IGVfc2VzX3NjaG9vbAogICkpCgojIFplaWdlIGRpZSBlcnN0ZW4gWmVpbGVuIGRlciB0cmFuc2Zvcm1pZXJ0ZW4gRGF0ZW4KI3ZpZXcoZV9zZXNfc2Nob29sKQpgYGAKCgojIGVfc2VzX3dhdGVyOiBFUi5IMk8uRldUTC5aUyAtIEFubnVhbCBmcmVzaHdhdGVyIHdpdGhkcmF3YWxzLCB0b3RhbCAoJSBvZiBpbnRlcm5hbCByZXNvdXJjZXMpCiMjIEFubnVhbCBmcmVzaHdhdGVyIHdpdGhkcmF3YWxzIHJlZmVyIHRvIHRvdGFsIHdhdGVyIHdpdGhkcmF3YWxzLCBub3QgY291bnRpbmcgZXZhcG9yYXRpb24gbG9zc2VzIGZyb20gc3RvcmFnZSBiYXNpbnMuIFdpdGhkcmF3YWxzIGFsc28gaW5jbHVkZSB3YXRlciBmcm9tIGRlc2FsaW5hdGlvbiBwbGFudHMgaW4gY291bnRyaWVzIHdoZXJlIHRoZXkgYXJlIGEgc2lnbmlmaWNhbnQgc291cmNlLiBXaXRoZHJhd2FscyBjYW4gZXhjZWVkIDEwMCBwZXJjZW50IG9mIHRvdGFsIHJlbmV3YWJsZSByZXNvdXJjZXMgd2hlcmUgZXh0cmFjdGlvbiBmcm9tIG5vbnJlbmV3YWJsZSBhcXVpZmVycyBvciBkZXNhbGluYXRpb24gcGxhbnRzIGlzIGNvbnNpZGVyYWJsZSBvciB3aGVyZSB0aGVyZSBpcyBzaWduaWZpY2FudCB3YXRlciByZXVzZS4gV2l0aGRyYXdhbHMgZm9yIGFncmljdWx0dXJlIGFuZCBpbmR1c3RyeSBhcmUgdG90YWwgd2l0aGRyYXdhbHMgZm9yIGlycmlnYXRpb24gYW5kIGxpdmVzdG9jayBwcm9kdWN0aW9uIGFuZCBmb3IgZGlyZWN0IGluZHVzdHJpYWwgdXNlIChpbmNsdWRpbmcgd2l0aGRyYXdhbHMgZm9yIGNvb2xpbmcgdGhlcm1vZWxlY3RyaWMgcGxhbnRzKS4gV2l0aGRyYXdhbHMgZm9yIGRvbWVzdGljIHVzZXMgaW5jbHVkZSBkcmlua2luZyB3YXRlciwgbXVuaWNpcGFsIHVzZSBvciBzdXBwbHksIGFuZCB1c2UgZm9yIHB1YmxpYyBzZXJ2aWNlcywgY29tbWVyY2lhbCBlc3RhYmxpc2htZW50cywgYW5kIGhvbWVzLiAKYGBge3J9CmNvdW50cmllcyA8LSBjKCJBRkciLCAiRFpBIiwgIkFORCIsICJBUkciLCAiQVJNIiwgIkFVUyIsICJBVVQiLCAiQVpFIiwgIkJHRCIsICJCTFIiLCAiQk9MIiwgIkJJSCIsICJCV0EiLCAiQlJBIiwgIkJHUiIsICJCRkEiLCAiS0hNIiwgIkNNUiIsICJDQU4iLCAiQ0hMIiwgIkNITiIsICJDT0wiLCAiQ1JJIiwgIkhSViIsICJDWVAiLCAiQ1pFIiwgIkVDVSIsICJFR1kiLCAiRVNUIiwgIkVUSCIsICJGSU4iLCAiRlJBIiwgIkdFTyIsICJERVUiLCAiR0hBIiwgIkdSQyIsICJHVE0iLCAiSFRJIiwgIkhLRyIsICJIVU4iLCAiSU5EIiwgIklETiIsICJJUk4iLCAiSVJRIiwgIklTUiIsICJJVEEiLCAiSlBOIiwgIkpPUiIsICJLQVoiLCAiS0VOIiwgIktXVCIsICJLR1oiLCAiTEJOIiwgIkxCWSIsICJMVFUiLCAiTVdJIiwgIk1ZUyIsICJNTEkiLCAiTUVYIiwgIk1EQSIsICJNQVIiLCAiTkxEIiwgIk5aTCIsICJOSUMiLCAiTkdBIiwgIk5PUiIsICJQQUsiLCAiUFNFIiwgIlBFUiIsICJQSEwiLCAiUE9MIiwgIlBSVCIsICJRQVQiLCAiUk9VIiwgIlJVUyIsICJSV0EiLCAiU0FVIiwgIlNSQiIsICJTR1AiLCAiU1ZOIiwgIlpBRiIsICJLT1IiLCAiRVNQIiwgIkxLQSIsICJTVVIiLCAiU1dFIiwgIkNIRSIsICJUV04iLCAiVFpBIiwgIlRIQSIsICJUVE8iLCAiVFVOIiwgIlRVUiIsICJVR0EiLCAiVUtSIiwgIkFSRSIsICJHQlIiLCAiVVNBIiwgIlVSWSIsICJVWkIiLCAiVkVOIiwgIlZOTSIsICJZRU0iLCAiWk1CIiwgIlpXRSIpICAgCmluZGljYXRvcnMgPC0gYygiRVIuSDJPLkZXVEwuWlMiKSAKCiMgRGF0ZW4gYWJydWZlbgplX3Nlc193YXRlciA8LSBXREkoY291bnRyeSA9IGNvdW50cmllcywgaW5kaWNhdG9yID0gaW5kaWNhdG9ycywgc3RhcnQgPSAyMDA1LCBlbmQgPSAyMDE0KQoKIyBTcGFsdGVuIHVtYmVuZW5uZW4KZV9zZXNfd2F0ZXIgPC0gZV9zZXNfd2F0ZXIgJT4lCiAgcmVuYW1lKGVfc2VzX3dhdGVyID0gYEVSLkgyTy5GV1RMLlpTYCkKCiMgRGF0ZW4gdHJhbnNmb3JtaWVyZW46IEphaHJlIGFscyBTcGFsdGVuIGRhcnN0ZWxsZW4KZV9zZXNfd2F0ZXIgPC0gZV9zZXNfd2F0ZXIgJT4lCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHllYXIsIHZhbHVlc19mcm9tID0gZV9zZXNfd2F0ZXIpCgojIER1cmNoc2Nobml0dCDDvGJlciBhbGxlIEphaHJlIGJlcmVjaG5lbiB1bmQgbmV1ZSBTcGFsdGUgaGluenVmw7xnZW4KZV9zZXNfd2F0ZXIgPC0gZV9zZXNfd2F0ZXIgJT4lCiAgbXV0YXRlKGVfc2VzX3dhdGVyID0gcm93TWVhbnMoc2VsZWN0KC4sIHN0YXJ0c193aXRoKCIyMCIpKSwgbmEucm0gPSBUUlVFKSkKCiMgUmVuYW1lIGlzbzNjIHRvIENPVU5UUlkKZV9zZXNfd2F0ZXIgPC0gZV9zZXNfd2F0ZXIgJT4lCiAgcmVuYW1lKENPVU5UUlkgPSBpc28zYykKCiMgV2VydGUgbWl0IDAgb2RlciBOYU4gZHVyY2ggTkEgZXJzZXR6ZW4KZV9zZXNfd2F0ZXIgPC0gZV9zZXNfd2F0ZXIgJT4lCiAgbXV0YXRlKGVfc2VzX3dhdGVyID0gY2FzZV93aGVuKAogICAgaXMubmFuKGVfc2VzX3dhdGVyKSB+IE5BX3JlYWxfLAogICAgZV9zZXNfd2F0ZXIgPT0gMCB+IE5BX3JlYWxfLAogICAgVFJVRSB+IGVfc2VzX3dhdGVyCiAgKSkKCiMgWmVpZ2UgZGllIGVyc3RlbiBaZWlsZW4gZGVyIHRyYW5zZm9ybWllcnRlbiBEYXRlbgojdmlldyhlX3Nlc193YXRlcikKYGBgCgoKIyBKb2luIFNwZWNpZmljYXRpb25zIHRvIGhhcmRzaGlwX0hTCmBgYHtyfQpoYXJkc2hpcF9lbnZpcm9ubWVudCA8LSBsZWZ0X2pvaW4oaGFyZHNoaXBfZW52aXJvbm1lbnQsIGVfb3RoX3NhZmV3YXRlclssIGMoIkNPVU5UUlkiLCAiZV9vdGhfc2FmZXdhdGVyIildLCBieSA9ICJDT1VOVFJZIikKaGFyZHNoaXBfZW52aXJvbm1lbnQgPC0gbGVmdF9qb2luKGhhcmRzaGlwX2Vudmlyb25tZW50LCBlX290aF9kcmlua2luZ3dhdGVyWywgYygiQ09VTlRSWSIsICJlX290aF9kcmlua2luZ3dhdGVyIildLCBieSA9ICJDT1VOVFJZIikKaGFyZHNoaXBfZW52aXJvbm1lbnQgPC0gbGVmdF9qb2luKGhhcmRzaGlwX2Vudmlyb25tZW50LCBlX2V4cF93YXRlcnNhbml0aHlnMTAwa1ssIGMoIkNPVU5UUlkiLCAiZV9leHBfd2F0ZXJzYW5pdGh5ZzEwMGsiKV0sIGJ5ID0gIkNPVU5UUlkiKQpoYXJkc2hpcF9lbnZpcm9ubWVudCA8LSBsZWZ0X2pvaW4oaGFyZHNoaXBfZW52aXJvbm1lbnQsIGVfZXhwX3dhdGVyc2FuaXRoeWdbLCBjKCJDT1VOVFJZIiwgImVfZXhwX3dhdGVyc2FuaXRoeWciKV0sIGJ5ID0gIkNPVU5UUlkiKQpoYXJkc2hpcF9lbnZpcm9ubWVudCA8LSBsZWZ0X2pvaW4oaGFyZHNoaXBfZW52aXJvbm1lbnQsIGVfZXhwX2Rpc2FzdGVyWywgYygiQ09VTlRSWSIsICJlX2V4cF9kaXNhc3RlciIpXSwgYnkgPSAiQ09VTlRSWSIpCmhhcmRzaGlwX2Vudmlyb25tZW50IDwtIGxlZnRfam9pbihoYXJkc2hpcF9lbnZpcm9ubWVudCwgZV9leHBfYWlyZGVhdGgxMDBrWywgYygiQ09VTlRSWSIsICJlX2V4cF9haXJkZWF0aDEwMGsiKV0sIGJ5ID0gIkNPVU5UUlkiKQpoYXJkc2hpcF9lbnZpcm9ubWVudCA8LSBsZWZ0X2pvaW4oaGFyZHNoaXBfZW52aXJvbm1lbnQsIGVfc2VzX2dpbmlbLCBjKCJDT1VOVFJZIiwgImVfc2VzX2dpbmkiKV0sIGJ5ID0gIkNPVU5UUlkiKQpoYXJkc2hpcF9lbnZpcm9ubWVudCA8LSBsZWZ0X2pvaW4oaGFyZHNoaXBfZW52aXJvbm1lbnQsIGVfc2VzX3VuZW1wbG95bWVudFssIGMoIkNPVU5UUlkiLCAiZV9zZXNfdW5lbXBsb3ltZW50IildLCBieSA9ICJDT1VOVFJZIikKaGFyZHNoaXBfZW52aXJvbm1lbnQgPC0gbGVmdF9qb2luKGhhcmRzaGlwX2Vudmlyb25tZW50LCBlX3Nlc19zY2hvb2xbLCBjKCJDT1VOVFJZIiwgImVfc2VzX3NjaG9vbCIpXSwgYnkgPSAiQ09VTlRSWSIpCmhhcmRzaGlwX2Vudmlyb25tZW50IDwtIGxlZnRfam9pbihoYXJkc2hpcF9lbnZpcm9ubWVudCwgZV9zZXNfd2F0ZXJbLCBjKCJDT1VOVFJZIiwgImVfc2VzX3dhdGVyIildLCBieSA9ICJDT1VOVFJZIikKCmhlYWQoaGFyZHNoaXBfZW52aXJvbm1lbnQpCmBgYAoKIyBNaXNzaW5nIENvdW50cmllcwpgYGB7cn0KIyBBdXN3YWhsIGFsbGVyIFNwYWx0ZW4sIGRpZSBtaXQgIkZfIiBiZWdpbm5lbgptaXNzaW5nX2NvdW50cmllcyA8LSBncmVwKCJeZV8iLCBuYW1lcyhoYXJkc2hpcF9lbnZpcm9ubWVudCksIHZhbHVlID0gVFJVRSkKCiMgQmVyZWNobnVuZyBkZXMgUHJvemVudHNhdHplcyBkZXIgZmVobGVuZGVuIFdlcnRlIHBybyBMYW5kCm1pc3NpbmdfcGVyY2VudGFnZXMgPC0gaGFyZHNoaXBfZW52aXJvbm1lbnQgJT4lCiAgc2VsZWN0KGNvdW50cnksIGFsbF9vZihtaXNzaW5nX2NvdW50cmllcykpICU+JQogIGdyb3VwX2J5KGNvdW50cnkpICU+JQogIHN1bW1hcmlzZV9lYWNoKGZ1bnMoc3VtKGlzLm5hKC4pKSAvIG4oKSAqIDEwMCksIGFsbF9vZihtaXNzaW5nX2NvdW50cmllcykpICU+JQogIG11dGF0ZShhdmVyYWdlX21pc3NpbmcgPSByb3dNZWFucyhzZWxlY3QoLiwgLWNvdW50cnkpLCBuYS5ybSA9IFRSVUUpKSAgJT4lCiAgYXJyYW5nZShkZXNjKGF2ZXJhZ2VfbWlzc2luZykpICAjIFNvcnRpZXJ0IGRpZSBEYXRlbiBhYnN0ZWlnZW5kIG5hY2ggZGVtIGR1cmNoc2Nobml0dGxpY2hlbiBQcm96ZW50c2F0eiBkZXIgZmVobGVuZGVuIFdlcnRlCgojIEF1c2dhYmUgZGVyIEVyZ2Vibmlzc2UKcHJpbnQobWlzc2luZ19wZXJjZW50YWdlcykKYGBgCgoKYGBge3J9CiMgTMOkbmRlciBIS0csIFJBVyB1bmQgVFdOIGF1cyBkZW0gRGF0ZW5zYXR6IGVudGZlcm5lbgpoYXJkc2hpcF9lbnZpcm9ubWVudCA8LSBoYXJkc2hpcF9lbnZpcm9ubWVudCAlPiUKICBmaWx0ZXIoIUNPVU5UUlkgJWluJSBjKCJUV04iLCAiQU5EIikpCgpoYXJkc2hpcF9lbnZpcm9ubWVudCA8LSBoYXJkc2hpcF9lbnZpcm9ubWVudCAlPiUKICBmaWx0ZXIoIWNvdW50cnkgJWluJSBjKCJTZXJiaWEgYW5kIE1vbnRlbmVncm8iKSkKCmhlYWQoaGFyZHNoaXBfZW52aXJvbm1lbnQpCmBgYAoKYGBge3J9CmhhcmRzaGlwX2Vudmlyb25tZW50IDwtIGhhcmRzaGlwX2Vudmlyb25tZW50ICU+JSBzZWxlY3QoQ09VTlRSWSwgY291bnRyeSwgYXZnX3Jpc2t0YWtpbmcsIGVfb3JpZ2luYWxfZ2luaSwgZV9vdGhfc2FmZXdhdGVyLCBlX290aF9kcmlua2luZ3dhdGVyLCBlX2V4cF93YXRlcnNhbml0aHlnMTAwaywgZV9leHBfd2F0ZXJzYW5pdGh5ZywgZV9leHBfZGlzYXN0ZXIsIGVfZXhwX2FpcmRlYXRoMTAwaywgZV9zZXNfZ2luaSwgZV9zZXNfdW5lbXBsb3ltZW50LCBlX3Nlc19zY2hvb2wsIGVfc2VzX3dhdGVyKQpzdHIoaGFyZHNoaXBfRmluYW5jZSkKYGBgCgojIE1pc3NpbmcgdmFsdWVzCgojIFByw7xmdW5nIGF1ZiBkZW4gTWVjaGFuaXNtdXMgZGVzIEZlaGxlbnMgdm9uIERhdGVuCmBgYHtyfQojIExhZGVuIGRlcyBQYWtldHMKbGlicmFyeShtaWNlKQpgYGAKCmBgYHtyfQojIExpdHRsZSdzIE1DQVItVGVzdCBkdXJjaGbDvGhyZW4KbWNhcl90ZXN0IDwtIG1pY2U6Om1kLnBhdHRlcm4oaGFyZHNoaXBfZW52aXJvbm1lbnQsIHBsb3QgPSBUUlVFKQoKIyBBdXNnYWJlIGRlcyBUZXN0ZXJnZWJuaXNzZXMKcHJpbnQobWNhcl90ZXN0KQpgYGAKCgpgYGB7cn0KIyBJbnN0YWxsaWVyZW4gZGVzIG5hbmlhciBQYWtldHMsIGZhbGxzIG5vY2ggbmljaHQgZ2VzY2hlaGVuCmlmICghcmVxdWlyZSgibmFuaWFyIikpIGluc3RhbGwucGFja2FnZXMoIm5hbmlhciIpCgojIExhZGVuIGRlcyBQYWtldHMKbGlicmFyeShuYW5pYXIpCgojIER1cmNoZsO8aHJ1bmcgdm9uIExpdHRsZSdzIE1DQVItVGVzdCAow6RobmxpY2gpCm1jYXJfdGVzdCA8LSBuYW5pYXI6Om1jYXJfdGVzdChoYXJkc2hpcF9lbnZpcm9ubWVudCkKCiMgQXVzZ2FiZSBkZXMgVGVzdGVyZ2Vibmlzc2VzCnByaW50KG1jYXJfdGVzdCkKYGBgCgoKCmBgYHtyfQpsaWJyYXJ5KG1pY2UpCgpsaWJyYXJ5KFZJTSkKYWdncl9wbG90IDwtIGFnZ3IoaGFyZHNoaXBfZW52aXJvbm1lbnQsIGNvbCA9IGMoJ25hdnlibHVlJywgJ3JlZCcpLCBudW1iZXJzID0gVFJVRSwgc29ydFZhcnMgPSBUUlVFLCAKICAgICAgICAgICAgICAgICAgbGFiZWxzID0gbmFtZXMoaGFyZHNoaXBfZW52aXJvbm1lbnQpLCBjZXguYXhpcyA9IDAuNywgZ2FwID0gMywgeWxhYiA9IGMoIk1pc3NpbmcgRGF0YSIsICJQYXR0ZXJuIikpCgp2aXNfbWlzcyhoYXJkc2hpcF9lbnZpcm9ubWVudCkKYGBgCgoKYGBge3J9CiMgQmVyZWNobnVuZyBkZXMgQW50ZWlscyBmZWhsZW5kZXIgV2VydGUgZsO8ciBqZWRlIFZhcmlhYmxlCm1pc3NpbmdfcGVyY2VudGFnZXMgPC0gc2FwcGx5KGhhcmRzaGlwX2Vudmlyb25tZW50LCBmdW5jdGlvbih4KSB7CiAgc3VtKGlzLm5hKHgpKSAvIGxlbmd0aCh4KSAqIDEwMAp9KQoKIyBBdXNnYWJlIGRlciBFcmdlYm5pc3NlCm1pc3NpbmdfcGVyY2VudGFnZXMKCiMgRGFyc3RlbGx1bmcgZGVyIEVyZ2Vibmlzc2UgaW4gZWluZW0gRGF0YWZyYW1lCm1pc3Npbmdfc3VtbWFyeSA8LSBkYXRhLmZyYW1lKAogIFZhcmlhYmxlID0gbmFtZXMobWlzc2luZ19wZXJjZW50YWdlcyksCiAgTWlzc2luZ1BlcmNlbnRhZ2UgPSBtaXNzaW5nX3BlcmNlbnRhZ2VzCikKCiMgU29ydGllcmUgZGllIFZhcmlhYmxlbiBuYWNoIGRlbSBQcm96ZW50c2F0eiBkZXIgZmVobGVuZGVuIFdlcnRlCm1pc3Npbmdfc3VtbWFyeSA8LSBtaXNzaW5nX3N1bW1hcnlbb3JkZXIoLW1pc3Npbmdfc3VtbWFyeSRNaXNzaW5nUGVyY2VudGFnZSksIF0KCiMgQXVzZ2FiZSBkZXIgVGFiZWxsZQpwcmludChtaXNzaW5nX3N1bW1hcnkpCgpgYGAKCgpgYGB7cn0KIyDDnGJlcnByw7xmZSwgb2IgYWxsZSBWYXJpYWJsZW4gdGF0c8OkY2hsaWNoIG51bWVyaXNjaCBzaW5kCnNhcHBseShoYXJkc2hpcF9lbnZpcm9ubWVudCwgZnVuY3Rpb24oeCkgYWxsKGlzLm51bWVyaWMoeCkpKQoKIyBFcnN0ZWxsZSBlaW5lbiBNZXRob2Rlbi1WZWt0b3IKbWV0aG9kcyA8LSByZXAoIm5vbmUiLCBuY29sKGhhcmRzaGlwX2Vudmlyb25tZW50KSkKbmFtZXMobWV0aG9kcykgPC0gY29sbmFtZXMoaGFyZHNoaXBfZW52aXJvbm1lbnQpCgojIFdlaXNlbiBkZW4gcmVsZXZhbnRlbiBTcGFsdGVuIEltcHV0YXRpb25zbWV0aG9kZW4genUKbWV0aG9kc1siZV9vcmlnaW5hbF9naW5pIl0gPC0gInBtbSIgICAgICAgIyBOdW1lcmlzY2gKbWV0aG9kc1siZV9vdGhfc2FmZXdhdGVyIl0gPC0gInBtbSIgICAgICAgICAgICAjIE51bWVyaXNjaAptZXRob2RzWyJlX2V4cF93YXRlcnNhbml0aHlnMTAwayJdIDwtICJwbW0iICAjIE51bWVyaXNjaAptZXRob2RzWyJlX3Nlc19naW5pIl0gPC0gInBtbSIgICAgICAgICAjIE51bWVyaXNjaAptZXRob2RzWyJlX3Nlc19zY2hvb2wiXSA8LSAicG1tIiAgICAgICAgIyBOdW1lcmlzY2gKbWV0aG9kc1siZV9leHBfZGlzYXN0ZXIiXSA8LSAicG1tIiAgICAgIyBOdW1lcmlzY2gKbWV0aG9kc1siZV9leHBfYWlyZGVhdGgxMDBrIl0gPC0gInBtbSIgICAgICAgICMgTnVtZXJpc2NoCm1ldGhvZHNbImVfZXhwX3dhdGVyc2FuaXRoeWciXSA8LSAicG1tIiAgICAgICAgICAgICAgIyBOdW1lcmlzY2gKbWV0aG9kc1siZV9zZXNfd2F0ZXIiXSA8LSAicG1tIiAgICAgICAgICAgIyBOdW1lcmlzY2gKbWV0aG9kc1siZV9vdGhfZHJpbmtpbmd3YXRlciJdIDwtICJwbW0iICAgICAgIyBOdW1lcmlzY2gKbWV0aG9kc1siZV9zZXNfdW5lbXBsb3ltZW50Il0gPC0gInBtbSIgICAgICAgICAgICMgTnVtZXJpc2NoCmBgYAoKCmBgYHtyfQojIEF1c3dhaGwgbnVyIGRlciBudW1lcmlzY2hlbiBTcGFsdGVuCmhhcmRzaGlwX2Vudmlyb25tZW50X251bWVyaWMgPC0gaGFyZHNoaXBfZW52aXJvbm1lbnQgJT4lCiAgc2VsZWN0KHdoZXJlKGlzLm51bWVyaWMpKSAlPiUKICBzZWxlY3QoLWF2Z19yaXNrdGFraW5nKQoKIyBEdXJjaGbDvGhydW5nIGRlciBJbXB1dGF0aW9uIG51ciBmw7xyIGRpZSBudW1lcmlzY2hlbiBTcGFsdGVuCmxpYnJhcnkobWljZSkKaW1wdXRlZF9kYXRhIDwtIG1pY2UoCiAgaGFyZHNoaXBfZW52aXJvbm1lbnRfbnVtZXJpYywKICBtID0gMjAsICAgICAgICAgICAgIyA1IHZvbGxzdMOkbmRpZ2UgRGF0ZW5zw6R0emUgZXJ6ZXVnZW4KICBtYXhpdCA9IDUwLCAgICAgICAjIE1heGltYWxlIEl0ZXJhdGlvbmVuCiAgc2VlZCA9IDEyMyAgICAgICAgIyBSZXByb2R1emllcmJhcmtlaXQKKQoKIyBadXNhbW1lbmZhc3N1bmcgZGVyIEltcHV0YXRpb25zZXJnZWJuaXNzZQpzdW1tYXJ5KGltcHV0ZWRfZGF0YSkKCiMgWnVncmlmZiBhdWYgZGVuIGVyc3RlbiB2b2xsc3TDpG5kaWcgaW1wdXRpZXJ0ZW4gRGF0ZW5zYXR6CmNvbXBsZXRlZF9kYXRhIDwtIGNvbXBsZXRlKGltcHV0ZWRfZGF0YSwgMSkKCiMgw5xiZXJwcsO8ZnVuZyBkZXIgU3RydWt0dXIgZGVzIHZvbGxzdMOkbmRpZ2VuIERhdGVuc2F0emVzCnN0cihjb21wbGV0ZWRfZGF0YSkKYGBgCgoKYGBge3J9CmltcHV0ZWRfZGF0YSRpbXAkZV9vdGhfc2FmZXdhdGVyICAjIFplaWd0IGRpZSBpbXB1dGllcnRlbiBXZXJ0ZSBmw7xyIGRpZXNlIFZhcmlhYmxlCmltcHV0ZWRfZGF0YSRpbXAkZV9leHBfd2F0ZXJzYW5pdGh5ZzEwMGsgICMgWmVpZ3QgZGllIGltcHV0aWVydGVuIFdlcnRlIGbDvHIgZGllc2UgVmFyaWFibGUKaW1wdXRlZF9kYXRhJGltcCRlX3Nlc19naW5pICAjIFplaWd0IGRpZSBpbXB1dGllcnRlbiBXZXJ0ZSBmw7xyIGRpZXNlIFZhcmlhYmxlCmltcHV0ZWRfZGF0YSRpbXAkZV9zZXNfc2Nob29sICAjIFplaWd0IGRpZSBpbXB1dGllcnRlbiBXZXJ0ZSBmw7xyIGRpZXNlIFZhcmlhYmxlCmltcHV0ZWRfZGF0YSRpbXAkZV9leHBfZGlzYXN0ZXIgICMgWmVpZ3QgZGllIGltcHV0aWVydGVuIFdlcnRlIGbDvHIgZGllc2UgVmFyaWFibGUKaW1wdXRlZF9kYXRhJGltcCRlX2V4cF9haXJkZWF0aDEwMGsgICMgWmVpZ3QgZGllIGltcHV0aWVydGVuIFdlcnRlIGbDvHIgZGllc2UgVmFyaWFibGUKaW1wdXRlZF9kYXRhJGltcCRlX2V4cF93YXRlcnNhbml0aHlnICAjIFplaWd0IGRpZSBpbXB1dGllcnRlbiBXZXJ0ZSBmw7xyIGRpZXNlIFZhcmlhYmxlCmltcHV0ZWRfZGF0YSRpbXAkZV9zZXNfd2F0ZXIgICMgWmVpZ3QgZGllIGltcHV0aWVydGVuIFdlcnRlIGbDvHIgZGllc2UgVmFyaWFibGUKaW1wdXRlZF9kYXRhJGltcCRlX290aF9kcmlua2luZ3dhdGVyICAjIFplaWd0IGRpZSBpbXB1dGllcnRlbiBXZXJ0ZSBmw7xyIGRpZXNlIFZhcmlhYmxlCmltcHV0ZWRfZGF0YSRpbXAkZV9zZXNfdW5lbXBsb3ltZW50ICAjIFplaWd0IGRpZSBpbXB1dGllcnRlbiBXZXJ0ZSBmw7xyIGRpZXNlIFZhcmlhYmxlCmltcHV0ZWRfZGF0YSRpbXAkZV9vcmlnaW5hbF9naW5pCgojIHZpc3VhbGlzaWVydW5nCnN0cmlwcGxvdChpbXB1dGVkX2RhdGEsIHBjaCA9IDIwLCBjZXggPSAxLjIpICAjIFZlcnRlaWx1bmcgZGVyIGltcHV0aWVydGVuIFdlcnRlCmRlbnNpdHlwbG90KGltcHV0ZWRfZGF0YSkgICMgRGljaHRlIGRlciBpbXB1dGllcnRlbiBXZXJ0ZQoKIyBJbXB1dGllcnRlIERhdGVuIGV4dHJhaGllcmVuCmNvbXBsZXRlZF9kYXRhIDwtIGNvbXBsZXRlKGltcHV0ZWRfZGF0YSwgYWN0aW9uID0gMSkKYGBgCgoKYGBge3J9CmxpYnJhcnkoZHBseXIpCgojIEJlcmVjaG51bmcgZGVyIE1pdHRlbHdlcnRlIHZvciBkZXIgSW1wdXRhdGlvbiwgYXVzc2NobGllw59lbmQgJ0NPVU5UUlknLCAnY291bnRyeScsICdhdmdfcmlza3Rha2luZycKbWVhbl92YWx1ZXNfcHJlX2ltcHV0YXRpb24gPC0gaGFyZHNoaXBfZW52aXJvbm1lbnQgJT4lCiAgc2VsZWN0KC1DT1VOVFJZLCAtY291bnRyeSwgLWF2Z19yaXNrdGFraW5nKSAlPiUgICMgQXVzc2NobHVzcyBkaWVzZXIgU3BhbHRlbgogIHNhcHBseShtZWFuLCBuYS5ybSA9IFRSVUUpCgojIEF1c2dhYmUgZGVyIE1pdHRlbHdlcnRlCnByaW50KG1lYW5fdmFsdWVzX3ByZV9pbXB1dGF0aW9uKQoKIyBCZXJlY2hudW5nIGRlciBNaXR0ZWx3ZXJ0ZSBuYWNoIGRlciBJbXB1dGF0aW9uCm1lYW5fdmFsdWVzX3Bvc3RfaW1wdXRhdGlvbiA8LSBjb21wbGV0ZWRfZGF0YSAlPiUKICBzYXBwbHkobWVhbiwgbmEucm0gPSBUUlVFKQoKIyBBdXNnYWJlIGRlciBNaXR0ZWx3ZXJ0ZQpwcmludChtZWFuX3ZhbHVlc19wb3N0X2ltcHV0YXRpb24pCgojIFZlcmdsZWljaCBkZXIgTWl0dGVsd2VydGUgdm9yIHVuZCBuYWNoIGRlciBJbXB1dGF0aW9uCmNvbXBhcmlzb25fZGF0YSA8LSBkYXRhLmZyYW1lKAogIFZhcmlhYmxlID0gbmFtZXMobWVhbl92YWx1ZXNfcHJlX2ltcHV0YXRpb24pLAogIFByZUltcHV0YXRpb24gPSBtZWFuX3ZhbHVlc19wcmVfaW1wdXRhdGlvbiwKICBQb3N0SW1wdXRhdGlvbiA9IG1lYW5fdmFsdWVzX3Bvc3RfaW1wdXRhdGlvbgopCgojIFBsb3R0ZW4gZGVyIE1pdHRlbHdlcnRlIHZvciB1bmQgbmFjaCBkZXIgSW1wdXRhdGlvbgpsaWJyYXJ5KGdncGxvdDIpCmdncGxvdChjb21wYXJpc29uX2RhdGEsIGFlcyh4ID0gVmFyaWFibGUpKSArCiAgZ2VvbV9iYXIoYWVzKHkgPSBQcmVJbXB1dGF0aW9uKSwgc3RhdCA9ICJpZGVudGl0eSIsIGZpbGwgPSAiYmx1ZSIsIGFscGhhID0gMC43KSArCiAgZ2VvbV9iYXIoYWVzKHkgPSBQb3N0SW1wdXRhdGlvbiksIHN0YXQgPSAiaWRlbnRpdHkiLCBmaWxsID0gInJlZCIsIGFscGhhID0gMC41KSArCiAgdGhlbWVfbWluaW1hbCgpICsKICBsYWJzKHRpdGxlID0gIlZlcmdsZWljaCBkZXIgTWl0dGVsd2VydGUgdm9yIHVuZCBuYWNoIGRlciBJbXB1dGF0aW9uIiwKICAgICAgIHkgPSAiTWl0dGVsd2VydCIsCiAgICAgICBmaWxsID0gIkxlZ2VuZGUiKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiUHJlLUltcHV0YXRpb24iID0gImJsdWUiLCAiUG9zdC1JbXB1dGF0aW9uIiA9ICJyZWQiKSkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0ID0gMSkpICAjIFZlcmJlc3NlcnQgZGllIExlc2JhcmtlaXQgZGVyIHgtQWNoc2VuYmVzY2hyaWZ0dW5nZW4KCmBgYAoKCmBgYHtyfQojIElkZW50aWZpemllcmVuIGRlciBnZW1laW5zYW1lbiBWYXJpYWJsZW5uYW1lbgpjb21tb25fbmFtZXMgPC0gaW50ZXJzZWN0KG5hbWVzKG1lYW5fdmFsdWVzX3ByZV9pbXB1dGF0aW9uKSwgbmFtZXMobWVhbl92YWx1ZXNfcG9zdF9pbXB1dGF0aW9uKSkKCiMgRXJzdGVsbHVuZyBkZXMgRGF0YWZyYW1lcyBudXIgbWl0IGRlbiBnZW1laW5zYW1lbiBWYXJpYWJsZW4KY29tcGFyaXNvbl9kYXRhIDwtIGRhdGEuZnJhbWUoCiAgVmFyaWFibGUgPSBjb21tb25fbmFtZXMsCiAgUHJlSW1wdXRhdGlvbiA9IG1lYW5fdmFsdWVzX3ByZV9pbXB1dGF0aW9uW2NvbW1vbl9uYW1lc10sCiAgUG9zdEltcHV0YXRpb24gPSBtZWFuX3ZhbHVlc19wb3N0X2ltcHV0YXRpb25bY29tbW9uX25hbWVzXQopCgojIMOcYmVycHLDvGZlbiBkZXIgRXJnZWJuaXNzZQpwcmludChjb21wYXJpc29uX2RhdGEpCmBgYAoKCgojIEbDvGdlIGRpZSBpbXB1dGllcnRlbiBWYXJpYWJsZW4genVyw7xjayBpbiBkZW4gdXJzcHLDvG5nbGljaGVuIERhdGVuc2F0eiBlaW46CmBgYHtyfQojIEdydXBwaWVydW5nIGVudGZlcm5lbgpoYXJkc2hpcF9lbnZpcm9ubWVudCA8LSBoYXJkc2hpcF9lbnZpcm9ubWVudCAlPiUKICB1bmdyb3VwKCkKCiMgRsO8Z2UgZGllIGltcHV0aWVydGVuIFZhcmlhYmxlbiB6dXLDvGNrIGluIGRlbiBEYXRlbnNhdHogZWluCmhhcmRzaGlwX2Vudmlyb25tZW50IDwtIGhhcmRzaGlwX2Vudmlyb25tZW50ICU+JQogIG11dGF0ZSgKICAgIGVfb3RoX3NhZmV3YXRlciA9IGNvbXBsZXRlZF9kYXRhJGVfb3RoX3NhZmV3YXRlciwKICAgIGVfZXhwX3dhdGVyc2FuaXRoeWcxMDBrID0gY29tcGxldGVkX2RhdGEkZV9leHBfd2F0ZXJzYW5pdGh5ZzEwMGssCiAgICBlX3Nlc19naW5pID0gY29tcGxldGVkX2RhdGEkZV9zZXNfZ2luaSwKICAgIGVfc2VzX3NjaG9vbCA9IGNvbXBsZXRlZF9kYXRhJGVfc2VzX3NjaG9vbCwKICAgIGVfZXhwX2Rpc2FzdGVyID0gY29tcGxldGVkX2RhdGEkZV9leHBfZGlzYXN0ZXIsCiAgICBlX2V4cF9haXJkZWF0aDEwMGsgPSBjb21wbGV0ZWRfZGF0YSRlX2V4cF9haXJkZWF0aDEwMGssCiAgICBlX2V4cF93YXRlcnNhbml0aHlnID0gY29tcGxldGVkX2RhdGEkZV9leHBfd2F0ZXJzYW5pdGh5ZywKICAgIGVfc2VzX3dhdGVyID0gY29tcGxldGVkX2RhdGEkZV9zZXNfd2F0ZXIKICApCgojIFN0cnVrdHVyIMO8YmVycHLDvGZlbgpzdHIoaGFyZHNoaXBfZW52aXJvbm1lbnQpCmBgYAoKCmBgYHtyfQpzdW0oaXMubmEoaGFyZHNoaXBfZW52aXJvbm1lbnQkZV9vdGhfc2FmZXdhdGVyKSkgICMgU29sbCAwIGVyZ2ViZW4Kc3VtKGlzLm5hKGhhcmRzaGlwX2Vudmlyb25tZW50JGVfZXhwX3dhdGVyc2FuaXRoeWcxMDBrKSkgICMgU29sbCAwIGVyZ2ViZW4Kc3VtKGlzLm5hKGhhcmRzaGlwX2Vudmlyb25tZW50JGVfc2VzX2dpbmkpKSAgIyBTb2xsIDAgZXJnZWJlbgpzdW0oaXMubmEoaGFyZHNoaXBfZW52aXJvbm1lbnQkZV9zZXNfc2Nob29sKSkgICMgU29sbCAwIGVyZ2ViZW4Kc3VtKGlzLm5hKGhhcmRzaGlwX2Vudmlyb25tZW50JGVfZXhwX2Rpc2FzdGVyKSkgICMgU29sbCAwIGVyZ2ViZW4Kc3VtKGlzLm5hKGhhcmRzaGlwX2Vudmlyb25tZW50JGVfZXhwX2FpcmRlYXRoMTAwaykpICAjIFNvbGwgMCBlcmdlYmVuCnN1bShpcy5uYShoYXJkc2hpcF9lbnZpcm9ubWVudCRlX2V4cF93YXRlcnNhbml0aHlnKSkgICMgU29sbCAwIGVyZ2ViZW4Kc3VtKGlzLm5hKGhhcmRzaGlwX2Vudmlyb25tZW50JGVfc2VzX3dhdGVyKSkgICMgU29sbCAwIGVyZ2ViZW4KYGBgCgojIyBjaGVjayBjb3VudHJ5ZmFjdHMgCmBgYHtyfQojIFBsb3QgaGlzdG9ncmFtcyBmb3IgZWFjaCBudW1lcmljIHZhcmlhYmxlCmhhcmRzaGlwX2Vudmlyb25tZW50ICU+JSAKICBzZWxlY3RfaWYoaXMubnVtZXJpYykgJT4lIAogIGdhdGhlcigpICU+JSAKICBnZ3Bsb3QoYWVzKHZhbHVlKSkgKyAKICBmYWNldF93cmFwKH5rZXksIHNjYWxlcyA9ICJmcmVlIikgKyAKICBnZW9tX2hpc3RvZ3JhbShiaW5zID0gMzApICsgCiAgdGhlbWVfbWluaW1hbCgpCmBgYAoKIyBBdXNyZWlzc2VyIApgYGB7cn0KIyAxLiBMb2dhcml0aG1pc2NoZSBUcmFuc2Zvcm1hdGlvbiBudXIgZsO8ciByZWxldmFudGUgVmFyaWFibGVuCmhhcmRzaGlwX2Vudmlyb25tZW50IDwtIGhhcmRzaGlwX2Vudmlyb25tZW50ICU+JQogIG11dGF0ZSgKICAgIGVfZXhwX3dhdGVyc2FuaXRoeWcgPSBsb2coZV9leHBfd2F0ZXJzYW5pdGh5ZyArIDEpLCAjIE51ciBmw7xyIGdyb8OfZSBXZXJ0ZWJlcmVpY2hlCiAgICBlX3Nlc193YXRlciA9IGxvZyhlX3Nlc193YXRlciArIDEpCiAgKQoKIyAyLiBXaW5zb3Jpc2llcnVuZyBudXIgYXVmIFZhcmlhYmxlbiBtaXQgcG90ZW56aWVsbGVuIEF1c3JlacOfZXJuCndpbnNvcml6ZSA8LSBmdW5jdGlvbih4LCBsb3dlcl9xdWFudGlsZSA9IDAuMDEsIHVwcGVyX3F1YW50aWxlID0gMC45OSkgewogIGxvd2VyIDwtIHF1YW50aWxlKHgsIGxvd2VyX3F1YW50aWxlLCBuYS5ybSA9IFRSVUUpCiAgdXBwZXIgPC0gcXVhbnRpbGUoeCwgdXBwZXJfcXVhbnRpbGUsIG5hLnJtID0gVFJVRSkKICBwbWluKHBtYXgoeCwgbG93ZXIpLCB1cHBlcikKfQoKaGFyZHNoaXBfZW52aXJvbm1lbnQgPC0gaGFyZHNoaXBfZW52aXJvbm1lbnQgJT4lCiAgbXV0YXRlKAogICAgZV9leHBfZGlzYXN0ZXIgPSB3aW5zb3JpemUoZV9leHBfZGlzYXN0ZXIpLAogICAgZV9leHBfYWlyZGVhdGgxMDBrID0gd2luc29yaXplKGVfZXhwX2FpcmRlYXRoMTAwayksCiAgICBlX3Nlc191bmVtcGxveW1lbnQgPSB3aW5zb3JpemUoZV9zZXNfdW5lbXBsb3ltZW50KQogICkKCiMgMy4gS2VpbmUgQW5wYXNzdW5nIGbDvHIgYW5kZXJlIFZhcmlhYmxlbiAoei4gQi4gZV9vdGhfc2FmZXdhdGVyKQojIMOcYmVycHLDvGZlbiBkZXIgU3RydWt0dXIgbmFjaCBUcmFuc2Zvcm1hdGlvbmVuCiMgdmlldyhoYXJkc2hpcF9lbnZpcm9ubWVudCkKYGBgCgpgYGB7cn0KIyBBbnBhc3N1bmcgZGVyIERhdGVuIHZvciBkZW0gTG9nYXJpdGhtaWVyZW4sIEVyc2V0emVuIHZvbiBOdWxsIG9kZXIgbmVnYXRpdmVuIFdlcnRlbiBkdXJjaCBlaW5lbiBrbGVpbmVuIHBvc2l0aXZlbiBXZXJ0CmhhcmRzaGlwX2Vudmlyb25tZW50IDwtIGhhcmRzaGlwX2Vudmlyb25tZW50ICU+JQogIG11dGF0ZSgKICAgIGVfZXhwX3dhdGVyc2FuaXRoeWcxMDBrID0gaWZlbHNlKGVfZXhwX3dhdGVyc2FuaXRoeWcxMDBrIDw9IDAsIDAuMSwgZV9leHBfd2F0ZXJzYW5pdGh5ZzEwMGspLAogICAgZV9leHBfZGlzYXN0ZXIgPSBpZmVsc2UoZV9leHBfZGlzYXN0ZXIgPD0gMCwgMC4xLCBlX2V4cF9kaXNhc3RlcikKICApCgojIEFud2VuZHVuZyBkZXIgTG9nYXJpdGhtdXMtVHJhbnNmb3JtYXRpb24gbWl0IGxvZzFwCmhhcmRzaGlwX2Vudmlyb25tZW50IDwtIGhhcmRzaGlwX2Vudmlyb25tZW50ICU+JQogIG11dGF0ZSgKICAgIGVfZXhwX3dhdGVyc2FuaXRoeWcxMDBrID0gbG9nMXAoZV9leHBfd2F0ZXJzYW5pdGh5ZzEwMGspLAogICAgZV9leHBfZGlzYXN0ZXIgPSBsb2cxcChlX2V4cF9kaXNhc3RlcikKICApCgojIMOcYmVycHLDvGZ1bmcgZGVyIERhdGVuIG5hY2ggZGVyIExvZ2FyaXRobXVzLVRyYW5zZm9ybWF0aW9uCnN1bW1hcnkoaGFyZHNoaXBfZW52aXJvbm1lbnQkZV9leHBfd2F0ZXJzYW5pdGh5ZzEwMGspCnN1bW1hcnkoaGFyZHNoaXBfZW52aXJvbm1lbnQkZV9leHBfZGlzYXN0ZXIpCmBgYAoKCiMjIFJldmVyc2UgQ29kaW5nIC0gU3RhbmRhcmRpemUgYW5kIGNyZWF0ZSBoYXJkc2hpcF9lbnZpcm9ubWVudApgYGB7cn0KbGlicmFyeShkcGx5cikKCiMgTG9nLXRyYW5zZm9ybSB0aGUgdmFyaWFibGVzIHVzaW5nIGRwbHlyCmhhcmRzaGlwX2Vudmlyb25tZW50IDwtIGhhcmRzaGlwX2Vudmlyb25tZW50ICU+JQogIG11dGF0ZSgKICAgIGVfb3RoX3NhZmV3YXRlciA9IGxvZyhlX290aF9zYWZld2F0ZXIpLAogICAgZV9zZXNfZ2luaSA9IGxvZyhlX3Nlc19naW5pKSwKICAgIGVfc2VzX3NjaG9vbCA9IGxvZyhlX3Nlc19zY2hvb2wpLAogICAgZV9leHBfYWlyZGVhdGgxMDBrID0gbG9nKGVfZXhwX2FpcmRlYXRoMTAwayksIAogICAgZV9vdGhfZHJpbmtpbmd3YXRlciA9IGxvZyhlX290aF9kcmlua2luZ3dhdGVyKSwgCiAgICBlX3Nlc191bmVtcGxveW1lbnQgPSBsb2coZV9zZXNfdW5lbXBsb3ltZW50KQogICkKCmhlYWQoaGFyZHNoaXBfZW52aXJvbm1lbnQpCnN0cihoYXJkc2hpcF9lbnZpcm9ubWVudCkKYGBgCgpgYGB7cn0KIyBQbG90IGhpc3RvZ3JhbXMgZm9yIGVhY2ggbnVtZXJpYyB2YXJpYWJsZQpoYXJkc2hpcF9lbnZpcm9ubWVudCAlPiUgCiAgc2VsZWN0X2lmKGlzLm51bWVyaWMpICU+JSAKICBnYXRoZXIoKSAlPiUgCiAgZ2dwbG90KGFlcyh2YWx1ZSkpICsgCiAgZmFjZXRfd3JhcCh+a2V5LCBzY2FsZXMgPSAiZnJlZSIpICsgCiAgZ2VvbV9oaXN0b2dyYW0oYmlucyA9IDMwKSArIAogIHRoZW1lX21pbmltYWwoKQpgYGAKCiMjIFJldmVyc2UgQ29kaW5nIC0gU3RhbmRhcmRpemUgYW5kIGNyZWF0ZSBoYXJkc2hpcF9IUwpgYGB7cn0KIyBOb3cgYXBwbHkgdGhlIHNjYWxlIGZ1bmN0aW9uIGFmdGVyIGNvbmZpcm1pbmcgYWxsIHZhcmlhYmxlcyBhcmUgbnVtZXJpYwpoYXJkc2hpcF9lbnZpcm9ubWVudCA8LSBoYXJkc2hpcF9lbnZpcm9ubWVudCAlPiUKICBtdXRhdGUoCiAgICBlX290aF9kcmlua2luZ3dhdGVyID0gc2NhbGUoLWVfb3RoX2RyaW5raW5nd2F0ZXIpLCAjIHJldmVyc2UgY29kaW5nCiAgICBlX290aF9zYWZld2F0ZXIgPSBzY2FsZSgtZV9vdGhfc2FmZXdhdGVyKSwgIyByZXZlcnNlIGNvZGluZyAKICAgIGVfZXhwX3dhdGVyc2FuaXRoeWcxMDBrID0gc2NhbGUoZV9leHBfd2F0ZXJzYW5pdGh5ZzEwMGspLAogICAgZV9zZXNfZ2luaSA9IHNjYWxlKGVfc2VzX2dpbmkpLCAKICAgIGVfc2VzX3NjaG9vbCA9IHNjYWxlKC1lX3Nlc19zY2hvb2wpLAogICAgZV9leHBfZGlzYXN0ZXIgPSBzY2FsZShlX2V4cF9kaXNhc3RlciksCiAgICBlX2V4cF9haXJkZWF0aDEwMGsgPSBzY2FsZShlX2V4cF9haXJkZWF0aDEwMGspLAogICAgZV9leHBfd2F0ZXJzYW5pdGh5ZyA9IHNjYWxlKGVfZXhwX3dhdGVyc2FuaXRoeWcpLCAKICAgIGVfc2VzX3VuZW1wbG95bWVudCA9IHNjYWxlKGVfc2VzX3VuZW1wbG95bWVudCksIAogICAgZV9zZXNfd2F0ZXIgPSBzY2FsZShlX3Nlc193YXRlcikKICApICU+JQogIHJvd3dpc2UoKSAlPiUKICBtdXRhdGUoCiAgICBoYXJkc2hpcF9IUyA9IG1lYW4oYyhlX290aF9kcmlua2luZ3dhdGVyLCBlX290aF9zYWZld2F0ZXIsIGVfZXhwX3dhdGVyc2FuaXRoeWcxMDBrLCBlX3Nlc19naW5pLCBlX3Nlc19zY2hvb2wsIGVfZXhwX2Rpc2FzdGVyLCBlX2V4cF9haXJkZWF0aDEwMGssIGVfZXhwX3dhdGVyc2FuaXRoeWcsIGVfc2VzX3VuZW1wbG95bWVudCwgZV9zZXNfd2F0ZXIpLCBuYS5ybSA9IFRSVUUpCiAgKSAlPiUKICB1bmdyb3VwKCkKCiN2aWV3KGhhcmRzaGlwX2Vudmlyb25tZW50KQpoZWFkKGhhcmRzaGlwX2Vudmlyb25tZW50KQpzdHIoaGFyZHNoaXBfZW52aXJvbm1lbnQpCgpgYGAKCiMgQ29ycmVsYXRpb24gSGVhdG1hcCB3aXRoIGFsbCB2YXJpYWJsZXMgCmBgYHtyfQojIEVyc3RlbGx1bmcgZGVyIEhlYXRtYXAgbWl0IEtvcnJlbGF0aW9uc2tvZWZmaXppZW50ZW4KbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KHJlc2hhcGUyKQoKIyBCZXJlY2hudW5nIGRlciBLb3JyZWxhdGlvbnNtYXRyaXgKY29yX21hdHJpeCA8LSBjb3IoaGFyZHNoaXBfZW52aXJvbm1lbnQgJT4lIHNlbGVjdF9pZihpcy5udW1lcmljKSwgdXNlID0gImNvbXBsZXRlLm9icyIpCgojIFVtd2FuZGx1bmcgZGVyIEtvcnJlbGF0aW9uc21hdHJpeCBpbiBlaW5lbiBEYXRlbnNhdHogZsO8ciBnZ3Bsb3QKbWVsdGVkX2Nvcl9tYXRyaXggPC0gbWVsdChjb3JfbWF0cml4KQoKIyBFcnN0ZWxsZW4gZGVyIEhlYXRtYXAgbWl0IEtvcnJlbGF0aW9uc2tvZWZmaXppZW50ZW4KZ2dwbG90KG1lbHRlZF9jb3JfbWF0cml4LCBhZXMoVmFyMSwgVmFyMiwgZmlsbCA9IHZhbHVlKSkgKwogIGdlb21fdGlsZSgpICsgICMgWmVpY2huZXQgZGllIEthY2hlbG4KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gc3ByaW50ZigiJS4yZiIsIHZhbHVlKSksIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDMpICsgICMgRsO8Z3QgZGllIEtvcnJlbGF0aW9uc2tvZWZmaXppZW50ZW4gaGluenUKICBzY2FsZV9maWxsX2dyYWRpZW50MihtaWRwb2ludCA9IDAsIGxvdyA9ICJibHVlIiwgaGlnaCA9ICJyZWQiLCBtaWQgPSAid2hpdGUiLCBsaW1pdCA9IGMoLTEsMSkpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpICsKICBsYWJzKGZpbGwgPSAiS29ycmVsYXRpb24iLCB4ID0gTlVMTCwgeSA9IE5VTEwpICsKICBjb29yZF9maXhlZCgpCgojIE9wdGlvbmFsOiBTcGVpY2hlcm4gZGVyIEhlYXRtYXAgYWxzIFBERgpnZ3NhdmUoImNvcnJlbGF0aW9uX2hlYXRtYXAucGRmIiwgd2lkdGggPSAxMSwgaGVpZ2h0ID0gOSwgcGF0aCA9IGJhc2VfcGF0aCkKYGBgCgojIENvcnJsYXRpb24gSGVhdG1hcCAKYGBge3J9CiMgQXVzd2FobCByZWxldmFudGVyIFNwYWx0ZW4Kc2VsZWN0ZWRfdmFycyA8LSBoYXJkc2hpcF9lbnZpcm9ubWVudCAlPiUgCiAgc2VsZWN0KGF2Z19yaXNrdGFraW5nLCBzdGFydHNfd2l0aCgiZV8iKSkKCiMgQmVyZWNobnVuZyBkZXIgS29ycmVsYXRpb25zbWF0cml4IGbDvHIgYXVzZ2V3w6RobHRlIFZhcmlhYmxlbgpjb3JfbWF0cml4IDwtIGNvcihzZWxlY3RlZF92YXJzLCB1c2UgPSAiY29tcGxldGUub2JzIikKCiMgVW13YW5kbHVuZyBkZXIgS29ycmVsYXRpb25zbWF0cml4IGluIGVpbmVuIERhdGVuc2F0eiBmw7xyIGdncGxvdAptZWx0ZWRfY29yX21hdHJpeCA8LSBtZWx0KGNvcl9tYXRyaXgpCgojIEVyc3RlbGx1bmcgZGVyIEhlYXRtYXAgbWl0IEtvcnJlbGF0aW9uc2tvZWZmaXppZW50ZW4KbGlicmFyeShnZ3Bsb3QyKQpnZ3Bsb3QobWVsdGVkX2Nvcl9tYXRyaXgsIGFlcyhWYXIxLCBWYXIyLCBmaWxsID0gdmFsdWUpKSArCiAgZ2VvbV90aWxlKCkgKyAgIyBaZWljaG5ldCBkaWUgS2FjaGVsbgogIGdlb21fdGV4dChhZXMobGFiZWwgPSBzcHJpbnRmKCIlLjJmIiwgdmFsdWUpKSwgY29sb3IgPSAiYmxhY2siLCBzaXplID0gMykgKyAgIyBGw7xndCBkaWUgS29ycmVsYXRpb25za29lZmZpemllbnRlbiBoaW56dQogIHNjYWxlX2ZpbGxfZ3JhZGllbnQyKG1pZHBvaW50ID0gMCwgbG93ID0gImJsdWUiLCBoaWdoID0gInJlZCIsIG1pZCA9ICJ3aGl0ZSIsIGxpbWl0ID0gYygtMSwxKSkgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSwgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkgKwogIGxhYnMoZmlsbCA9ICJLb3JyZWxhdGlvbiIsIHggPSBOVUxMLCB5ID0gTlVMTCkgKwogIGNvb3JkX2ZpeGVkKCkKYGBgCgojIENyb25iYWNocyBBbHBoYQpgYGB7cn0KbGlicmFyeShwc3ljaCkKCiMgU2ljaGVyc3RlbGxlbiwgZGFzcyBhbGxlIHJlbGV2YW50ZW4gJ0hTXyctU3BhbHRlbiBhdXNnZXfDpGhsdCB3ZXJkZW4KaXRlbXMgPC0gaGFyZHNoaXBfZW52aXJvbm1lbnQgJT4lCiAgc2VsZWN0KGVfb3JpZ2luYWxfZ2luaSwgZV9vdGhfZHJpbmtpbmd3YXRlciwgZV9vdGhfc2FmZXdhdGVyLCBlX2V4cF93YXRlcnNhbml0aHlnMTAwaywgZV9zZXNfZ2luaSwgZV9zZXNfc2Nob29sLCBlX2V4cF9kaXNhc3RlciwgZV9leHBfYWlyZGVhdGgxMDBrLCBlX2V4cF93YXRlcnNhbml0aHlnLCBlX3Nlc191bmVtcGxveW1lbnQsIGVfc2VzX3dhdGVyKQoKIyBCZXJlY2hudW5nIHZvbiBDcm9uYmFjaHMgQWxwaGEKYWxwaGFfcmVzdWx0IDwtIGFscGhhKGl0ZW1zKQpwcmludChhbHBoYV9yZXN1bHQpCmBgYAoKCiMgQ29ycmxhdGlvbiBIZWF0bWFwIHdpdGhvdXQgZV9zZXNfd2F0ZXIsIGVfc2VzX3VuZW1wbG95bWVudApgYGB7cn0KbGlicmFyeShkcGx5cikKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KHJlc2hhcGUyKSAgIyBTb2xsdGUgZ2VsYWRlbiBzZWluLCB3ZW5uIGBtZWx0YCB2ZXJ3ZW5kZXQgd2lyZAoKIyBBdXN3YWhsIHJlbGV2YW50ZXIgU3BhbHRlbiwgYXVzc2NobGllw59lbmQgZV9zZXNfd2F0ZXIgdW5kIGVfc2VzX3VuZW1wbG95bWVudApzZWxlY3RlZF92YXJzIDwtIGhhcmRzaGlwX2Vudmlyb25tZW50ICU+JQogIHNlbGVjdChhdmdfcmlza3Rha2luZywgc3RhcnRzX3dpdGgoImVfIiksIC1lX3Nlc193YXRlciwgLWVfc2VzX3VuZW1wbG95bWVudCkKCiMgQmVyZWNobnVuZyBkZXIgS29ycmVsYXRpb25zbWF0cml4IGbDvHIgYXVzZ2V3w6RobHRlIFZhcmlhYmxlbgpjb3JfbWF0cml4IDwtIGNvcihzZWxlY3RlZF92YXJzLCB1c2UgPSAiY29tcGxldGUub2JzIikKCiMgVW13YW5kbHVuZyBkZXIgS29ycmVsYXRpb25zbWF0cml4IGluIGVpbmVuIERhdGVuc2F0eiBmw7xyIGdncGxvdCBtaXQgYG1lbHRgIGF1cyBkZW0gcmVzaGFwZTItUGFrZXQKbWVsdGVkX2Nvcl9tYXRyaXggPC0gbWVsdChjb3JfbWF0cml4KQoKIyBFcnN0ZWxsdW5nIGRlciBIZWF0bWFwIG1pdCBLb3JyZWxhdGlvbnNrb2VmZml6aWVudGVuCmdncGxvdChtZWx0ZWRfY29yX21hdHJpeCwgYWVzKFZhcjEsIFZhcjIsIGZpbGwgPSB2YWx1ZSkpICsKICBnZW9tX3RpbGUoKSArICAjIFplaWNobmV0IGRpZSBLYWNoZWxuCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHNwcmludGYoIiUuMmYiLCB2YWx1ZSkpLCBjb2xvciA9ICJibGFjayIsIHNpemUgPSAzKSArICAjIEbDvGd0IGRpZSBLb3JyZWxhdGlvbnNrb2VmZml6aWVudGVuIGhpbnp1CiAgc2NhbGVfZmlsbF9ncmFkaWVudDIobWlkcG9pbnQgPSAwLCBsb3cgPSAiYmx1ZSIsIGhpZ2ggPSAicmVkIiwgbWlkID0gIndoaXRlIiwgbGltaXRzID0gYygtMSwgMSkpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSksIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpICsKICBsYWJzKGZpbGwgPSAiS29ycmVsYXRpb24iLCB4ID0gTlVMTCwgeSA9IE5VTEwpICsKICBjb29yZF9maXhlZCgpCmBgYAojIENyb25iYWNocyBBbHBoYQpgYGB7cn0KbGlicmFyeShwc3ljaCkKCiMgU2ljaGVyc3RlbGxlbiwgZGFzcyBhbGxlIHJlbGV2YW50ZW4gJ0hTXyctU3BhbHRlbiBhdXNnZXfDpGhsdCB3ZXJkZW4KaXRlbXMgPC0gaGFyZHNoaXBfZW52aXJvbm1lbnQgJT4lCiAgc2VsZWN0KGVfb3JpZ2luYWxfZ2luaSwgZV9vdGhfZHJpbmtpbmd3YXRlciwgZV9vdGhfc2FmZXdhdGVyLCBlX2V4cF93YXRlcnNhbml0aHlnMTAwaywgZV9zZXNfZ2luaSwgZV9zZXNfc2Nob29sLCBlX2V4cF9kaXNhc3RlciwgZV9leHBfYWlyZGVhdGgxMDBrLCBlX2V4cF93YXRlcnNhbml0aHlnKQoKIyBCZXJlY2hudW5nIHZvbiBDcm9uYmFjaHMgQWxwaGEKYWxwaGFfcmVzdWx0IDwtIGFscGhhKGl0ZW1zKQpwcmludChhbHBoYV9yZXN1bHQpCmBgYAoKYGBge3J9CmhhcmRzaGlwX2Vudmlyb25tZW50IDwtIGhhcmRzaGlwX2Vudmlyb25tZW50ICU+JSBzZWxlY3QoQ09VTlRSWSwgY291bnRyeSwgYXZnX3Jpc2t0YWtpbmcsIGVfb3JpZ2luYWxfZ2luaSwgZV9vdGhfZHJpbmtpbmd3YXRlciwgZV9vdGhfc2FmZXdhdGVyLCBlX2V4cF93YXRlcnNhbml0aHlnMTAwaywgZV9zZXNfZ2luaSwgZV9zZXNfc2Nob29sLCBlX2V4cF9kaXNhc3RlciwgZV9leHBfYWlyZGVhdGgxMDBrLCBlX2V4cF93YXRlcnNhbml0aHlnKQpgYGAKCgpgYGB7cn0Kd3JpdGUuY3N2KGhhcmRzaGlwX2Vudmlyb25tZW50LCBmaWxlID0gZmlsZS5wYXRoKGJhc2VfcGF0aCwgImhhcmRzaGlwX2Vudmlyb25tZW50LmNzdiIpLCByb3cubmFtZXMgPSBGQUxTRSkKYGBg